From 1d3b65f2cd05b2b27dc1d1afea11d6e9de9af864 Mon Sep 17 00:00:00 2001 From: Sayali Gaikawad <61760125+gaiksaya@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:36:13 -0800 Subject: [PATCH] Combine create and close GH issues for build failures into one library (#380) Signed-off-by: Sayali Gaikawad --- build.gradle | 2 +- .../TestUpdateBuildFailuresIssues.groovy | 97 +++++++++++++++ .../jobs/UpdateBuildFailureIssue_Jenkinsfile | 25 ++++ .../UpdateBuildFailureIssue_Jenkinsfile.txt | 117 ++++++++++++++++++ .../UpdateBuildFailureIssuesLibTester.groovy | 49 ++++++++ vars/UpdateBuildFailureIssues.groovy | 74 +++++++++++ 6 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 tests/jenkins/TestUpdateBuildFailuresIssues.groovy create mode 100644 tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile create mode 100644 tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile.txt create mode 100644 tests/jenkins/lib-testers/UpdateBuildFailureIssuesLibTester.groovy create mode 100644 vars/UpdateBuildFailureIssues.groovy diff --git a/build.gradle b/build.gradle index 29b3e7253..1fa94c390 100644 --- a/build.gradle +++ b/build.gradle @@ -121,7 +121,7 @@ jacocoTestReport { } } -String version = '6.2.0' +String version = '6.3.0' task updateVersion { doLast { diff --git a/tests/jenkins/TestUpdateBuildFailuresIssues.groovy b/tests/jenkins/TestUpdateBuildFailuresIssues.groovy new file mode 100644 index 000000000..f49880c9d --- /dev/null +++ b/tests/jenkins/TestUpdateBuildFailuresIssues.groovy @@ -0,0 +1,97 @@ +/* + * 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 org.junit.Before +import org.junit.Test +import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString +import static org.hamcrest.CoreMatchers.hasItem +import static org.hamcrest.CoreMatchers.not +import static org.hamcrest.MatcherAssert.assertThat + +class TestUpdateBuildFailuresIssues extends BuildPipelineTest { + + @Override + @Before + void setUp() { + this.registerLibTester(new UpdateBuildFailureIssuesLibTester(["Error building common-utils, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component common-utils", "Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0ed in the next build. This might have performance impact if it keeps failing. Run the javaToolchains task for more det.yml --component performance-analyzer", "Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search", "Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search", "Error building anomaly-detection, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component anomaly-detection", "Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component performance-analyzer", "Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications"], ["Successfully built sql", "Successfully built notifications", "Successfully built notifications", "Successfully built sql", "Successfully built anomaly-detection", "Successfully built index-management", "Successfully built sql", "Successfully built anomaly-detection"], 'tests/data/opensearch-2.2.0.yml')) + super.setUp() + } + + @Test + public void testCreateGithubIssue() { + helper.addShMock("date -d \"3 days ago\" +'%Y-%m-%d'") { script -> + return [stdout: "2023-10-24", exitValue: 0] + } + + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "", exitValue: 0] + } + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "", exitValue: 0] + } + super.testPipeline('tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile') + assertThat(getCommands('sh', 'create'), hasItem('{script=gh issue create --title \"[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0\" --body \"***Received Error***: **Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search**.\n asynchronous-search failed during the distribution build for version: 2.2.0.\n Please see build log at www.example.com/job/build_url/32/display/redirect.\n The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details\" --label autocut,v2.2.0 --label \"untriaged\" --repo https://github.com/opensearch-project/asynchronous-search.git, returnStdout=true}')) + } + + @Test + public void testCommentOnExistingGithubIssue() { + helper.addShMock("date -d \"3 days ago\" +'%Y-%m-%d'") { script -> + return [stdout: "2023-10-24", exitValue: 0] + } + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "22", exitValue: 0] + } + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "", exitValue: 0] + } + runScript('tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile') + assertThat(getCommands('println', ''), hasItem('Issue already exists, adding a comment')) + assertThat(getCommands('sh', 'script'), hasItem("{script=gh issue comment 22 --repo https://github.com/opensearch-project/asynchronous-search.git --body \"***Received Error***: **Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search**.\n asynchronous-search failed during the distribution build for version: 2.2.0.\n Please see build log at www.example.com/job/build_url/32/display/redirect.\n The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details\", returnStdout=true}")) + } + + @Test + public void testClosingGithubIssueOnSuccess() { + helper.addShMock("date -d \"3 days ago\" +'%Y-%m-%d'") { script -> + return [stdout: "2023-10-24", exitValue: 0] + } + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/sql.git -S "[AUTOCUT] Distribution Build Failed for sql-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "30", exitValue: 0] + } + runScript('tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile') + assertThat(getCommands('sh', 'sql'), hasItem("{script=gh issue list --repo https://github.com/opensearch-project/sql.git -S \"[AUTOCUT] Distribution Build Failed for sql-2.2.0 in:title\" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}")) + assertThat(getCommands('sh', 'sql'), hasItem("{script=gh issue close 30 -R opensearch-project/sql --comment \"Closing the issue as the distribution build for sql has passed for version: **2.2.0**.\n Please see build log at www.example.com/job/build_url/32/display/redirect\", returnStdout=true}")) + } + + @Test + public void testNotClosingGithubIssueOnOneFailure() { + helper.addShMock("date -d \"3 days ago\" +'%Y-%m-%d'") { script -> + return [stdout: "2023-10-24", exitValue: 0] + } + helper.addShMock("""gh issue list --repo https://github.com/opensearch-project/notifications.git -S "[AUTOCUT] Distribution Build Failed for notifications-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number'""") { script -> + return [stdout: "20", exitValue: 0] + } + runScript('tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile') + assertThat(getCommands('sh', 'notifications'), not(hasItem("{script=gh issue close 20 -R opensearch-project/notifications --comment \"Closing the issue as the distribution build for notifications has passed for version: **2.2.0**.\n Please see build log at www.example.com/job/build_url/32/display/redirect\", returnStdout=true}"))) + assertThat(getCommands('sh', 'script'), hasItem("{script=gh issue comment 20 --repo https://github.com/opensearch-project/notifications.git --body \"***Received Error***: **Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications**.\n notifications failed during the distribution build for version: 2.2.0.\n Please see build log at www.example.com/job/build_url/32/display/redirect.\n The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details\", returnStdout=true}")) + } + + def getCommands(method, text) { + def shCommands = helper.callStack.findAll { call -> + call.methodName == method + }.collect { call -> + callArgsToString(call) + }.findAll { command -> + command.contains(text) + } + return shCommands + } + +} diff --git a/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile b/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile new file mode 100644 index 000000000..44afd89da --- /dev/null +++ b/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile @@ -0,0 +1,25 @@ +/* + * 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('updateBuildFailureIssue') { + steps { + script { + UpdateBuildFailureIssues( + failureMessages: ["Error building common-utils, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component common-utils", "Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0ed in the next build. This might have performance impact if it keeps failing. Run the javaToolchains task for more det.yml --component performance-analyzer", "Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search", "Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search", "Error building anomaly-detection, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component anomaly-detection", "Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component performance-analyzer", "Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications"], + passMessages: ["Successfully built sql", "Successfully built notifications", "Successfully built notifications", "Successfully built sql", "Successfully built anomaly-detection", "Successfully built index-management", "Successfully built sql", "Successfully built anomaly-detection"], + inputManifestPath: 'tests/data/opensearch-2.2.0.yml' + ) + } + } + } + } +} diff --git a/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile.txt b/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile.txt new file mode 100644 index 000000000..94af12299 --- /dev/null +++ b/tests/jenkins/jobs/UpdateBuildFailureIssue_Jenkinsfile.txt @@ -0,0 +1,117 @@ + UpdateBuildFailureIssue_Jenkinsfile.run() + UpdateBuildFailureIssue_Jenkinsfile.pipeline(groovy.lang.Closure) + UpdateBuildFailureIssue_Jenkinsfile.echo(Executing on agent [label:none]) + UpdateBuildFailureIssue_Jenkinsfile.stage(updateBuildFailureIssue, groovy.lang.Closure) + UpdateBuildFailureIssue_Jenkinsfile.script(groovy.lang.Closure) + UpdateBuildFailureIssue_Jenkinsfile.UpdateBuildFailureIssues({failureMessages=[Error building common-utils, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component common-utils, Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0ed in the next build. This might have performance impact if it keeps failing. Run the javaToolchains task for more det.yml --component performance-analyzer, Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search, Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search, Error building anomaly-detection, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component anomaly-detection, Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component performance-analyzer, Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications], passMessages=[Successfully built sql, Successfully built notifications, Successfully built notifications, Successfully built sql, Successfully built anomaly-detection, Successfully built index-management, Successfully built sql, Successfully built anomaly-detection], inputManifestPath=tests/data/opensearch-2.2.0.yml}) + UpdateBuildFailureIssues.legacySCM(groovy.lang.Closure) + UpdateBuildFailureIssues.library({identifier=jenkins@main, retriever=null}) + UpdateBuildFailureIssues.readYaml({file=tests/data/opensearch-2.2.0.yml}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.createGithubIssue({repoUrl=https://github.com/opensearch-project/common-utils.git, issueTitle=[AUTOCUT] Distribution Build Failed for common-utils-2.2.0, issueBody=***Received Error***: **Error building common-utils, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component common-utils**. + common-utils failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details, label=autocut,v2.2.0}) + createGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + createGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/common-utils.git -S "[AUTOCUT] Distribution Build Failed for common-utils-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.sh({script=date -d "3 days ago" +'%Y-%m-%d', returnStdout=true}) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/common-utils.git -S "[AUTOCUT] Distribution Build Failed for common-utils-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.println(Issue already exists, adding a comment) + createGithubIssue.sh({script=gh issue comment bbb +ccc --repo https://github.com/opensearch-project/common-utils.git --body "***Received Error***: **Error building common-utils, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component common-utils**. + common-utils failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.createGithubIssue({repoUrl=https://github.com/opensearch-project/performance-analyzer.git, issueTitle=[AUTOCUT] Distribution Build Failed for performance-analyzer-2.2.0, issueBody=***Received Error***: **Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0ed in the next build. This might have performance impact if it keeps failing. Run the javaToolchains task for more det.yml --component performance-analyzer**. + performance-analyzer failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details, label=autocut,v2.2.0}) + createGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + createGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/performance-analyzer.git -S "[AUTOCUT] Distribution Build Failed for performance-analyzer-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.sh({script=date -d "3 days ago" +'%Y-%m-%d', returnStdout=true}) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/performance-analyzer.git -S "[AUTOCUT] Distribution Build Failed for performance-analyzer-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.println(Issue already exists, adding a comment) + createGithubIssue.sh({script=gh issue comment bbb +ccc --repo https://github.com/opensearch-project/performance-analyzer.git --body "***Received Error***: **Error building performance-analyzer, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0ed in the next build. This might have performance impact if it keeps failing. Run the javaToolchains task for more det.yml --component performance-analyzer**. + performance-analyzer failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.createGithubIssue({repoUrl=https://github.com/opensearch-project/notifications.git, issueTitle=[AUTOCUT] Distribution Build Failed for notifications-2.2.0, issueBody=***Received Error***: **Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications**. + notifications failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details, label=autocut,v2.2.0}) + createGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + createGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/notifications.git -S "[AUTOCUT] Distribution Build Failed for notifications-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.sh({script=date -d "3 days ago" +'%Y-%m-%d', returnStdout=true}) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/notifications.git -S "[AUTOCUT] Distribution Build Failed for notifications-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.println(Issue already exists, adding a comment) + createGithubIssue.sh({script=gh issue comment bbb +ccc --repo https://github.com/opensearch-project/notifications.git --body "***Received Error***: **Error building notifications, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component notifications**. + notifications failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.createGithubIssue({repoUrl=https://github.com/opensearch-project/anomaly-detection.git, issueTitle=[AUTOCUT] Distribution Build Failed for anomaly-detection-2.2.0, issueBody=***Received Error***: **Error building anomaly-detection, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component anomaly-detection**. + anomaly-detection failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details, label=autocut,v2.2.0}) + createGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + createGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/anomaly-detection.git -S "[AUTOCUT] Distribution Build Failed for anomaly-detection-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.sh({script=date -d "3 days ago" +'%Y-%m-%d', returnStdout=true}) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/anomaly-detection.git -S "[AUTOCUT] Distribution Build Failed for anomaly-detection-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.println(Issue already exists, adding a comment) + createGithubIssue.sh({script=gh issue comment bbb +ccc --repo https://github.com/opensearch-project/anomaly-detection.git --body "***Received Error***: **Error building anomaly-detection, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component anomaly-detection**. + anomaly-detection failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.createGithubIssue({repoUrl=https://github.com/opensearch-project/asynchronous-search.git, issueTitle=[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0, issueBody=***Received Error***: **Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search**. + asynchronous-search failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details, label=autocut,v2.2.0}) + createGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + createGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.sh({script=date -d "3 days ago" +'%Y-%m-%d', returnStdout=true}) + createGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/asynchronous-search.git -S "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0 in:title is:closed closed:>=2023-10-24" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + createGithubIssue.println(Creating new issue) + createGithubIssue.sh({script=gh issue create --title "[AUTOCUT] Distribution Build Failed for asynchronous-search-2.2.0" --body "***Received Error***: **Error building asynchronous-search, retry with: ./build.sh manifests/2.2.0/opensearch-2.2.0.yml --component asynchronous-search**. + asynchronous-search failed during the distribution build for version: 2.2.0. + Please see build log at www.example.com/job/build_url/32/display/redirect. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details" --label autocut,v2.2.0 --label "untriaged" --repo https://github.com/opensearch-project/asynchronous-search.git, returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.closeGithubIssue({repoUrl=https://github.com/opensearch-project/index-management.git, issueTitle=[AUTOCUT] Distribution Build Failed for index-management-2.2.0, closeComment=Closing the issue as the distribution build for index-management has passed for version: **2.2.0**. + Please see build log at www.example.com/job/build_url/32/display/redirect, label=autocut,v2.2.0}) + closeGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + closeGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + closeGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/index-management.git -S "[AUTOCUT] Distribution Build Failed for index-management-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + closeGithubIssue.sh({script=gh issue close bbb +ccc -R opensearch-project/index-management --comment "Closing the issue as the distribution build for index-management has passed for version: **2.2.0**. + Please see build log at www.example.com/job/build_url/32/display/redirect", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.closeGithubIssue({repoUrl=https://github.com/opensearch-project/sql.git, issueTitle=[AUTOCUT] Distribution Build Failed for sql-2.2.0, closeComment=Closing the issue as the distribution build for sql has passed for version: **2.2.0**. + Please see build log at www.example.com/job/build_url/32/display/redirect, label=autocut,v2.2.0}) + closeGithubIssue.usernamePassword({credentialsId=jenkins-github-bot-token, passwordVariable=GITHUB_TOKEN, usernameVariable=GITHUB_USER}) + closeGithubIssue.withCredentials([[GITHUB_USER, GITHUB_TOKEN]], groovy.lang.Closure) + closeGithubIssue.sh({script=gh issue list --repo https://github.com/opensearch-project/sql.git -S "[AUTOCUT] Distribution Build Failed for sql-2.2.0 in:title" --label autocut,v2.2.0 --json number --jq '.[0].number', returnStdout=true}) + closeGithubIssue.sh({script=gh issue close bbb +ccc -R opensearch-project/sql --comment "Closing the issue as the distribution build for sql has passed for version: **2.2.0**. + Please see build log at www.example.com/job/build_url/32/display/redirect", returnStdout=true}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) + UpdateBuildFailureIssues.sleep({time=3, unit=SECONDS}) diff --git a/tests/jenkins/lib-testers/UpdateBuildFailureIssuesLibTester.groovy b/tests/jenkins/lib-testers/UpdateBuildFailureIssuesLibTester.groovy new file mode 100644 index 000000000..41b5782aa --- /dev/null +++ b/tests/jenkins/lib-testers/UpdateBuildFailureIssuesLibTester.groovy @@ -0,0 +1,49 @@ +/* + * 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.CoreMatchers.nullValue +import static org.hamcrest.MatcherAssert.assertThat + +class UpdateBuildFailureIssuesLibTester extends LibFunctionTester{ + private List failureMessages + private List passMessages + private String inputManifestPath + + public UpdateBuildFailureIssuesLibTester(failureMessages, passMessages, inputManifestPath){ + this.failureMessages = failureMessages + this.passMessages = passMessages + this.inputManifestPath = inputManifestPath + } + + @Override + String libFunctionName() { + return 'UpdateBuildFailureIssues' + } + + @Override + void parameterInvariantsAssertions(Object call) { + assertThat(call.args.failureMessages.first(), notNullValue()) + assertThat(call.args.passMessages.first(), notNullValue()) + assertThat(call.args.inputManifestPath.first(), notNullValue()) + } + + @Override + boolean expectedParametersMatcher(Object call) { + return call.args.failureMessages.first().equals(this.failureMessages) + && call.args.passMessages.first().equals(this.passMessages) + && call.args.inputManifestPath.first().equals(this.inputManifestPath) + } + + @Override + void configure(Object helper, Object binding) { + helper.registerAllowedMethod('withCredentials', [Map]) + helper.registerAllowedMethod('sleep', [Map]) + binding.setVariable('env', ['RUN_DISPLAY_URL': 'www.example.com/job/build_url/32/display/redirect']) + } +} diff --git a/vars/UpdateBuildFailureIssues.groovy b/vars/UpdateBuildFailureIssues.groovy new file mode 100644 index 000000000..ab7848fc3 --- /dev/null +++ b/vars/UpdateBuildFailureIssues.groovy @@ -0,0 +1,74 @@ +/* + * 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 create, update an close GitHub issue across opensearch-project repositories for distribution build failures. + @param Map args = [:] args A map of the following parameters + @param args.failureMessages - Failure message retrieved from buildFailureMessage() method. + @param args.passMessages - Passing message retrieved from buildFailureMessage() method. + @param args.inputManifestPath - Path to input manifest. + */ +void call(Map args = [:]) { + lib = library(identifier: 'jenkins@main', retriever: legacySCM(scm)) + def failureMessages = args.failureMessages + def passMessages = args.passMessages + def inputManifest = readYaml(file: args.inputManifestPath) + def currentVersion = inputManifest.build.version + + List failedComponents = [] + List passedComponents = [] + + for (message in failureMessages) { + java.util.regex.Matcher match = (message =~ /(?<=\bError building\s).*/) + String matched = match[0] + failedComponents.add(matched.split(' ')[0].split(',')[0].trim()) + } + failedComponents = failedComponents.unique() + for (message in passMessages) { + java.util.regex.Matcher match = (message =~ /(?<=\bSuccessfully built\s).*/) + String matched = match[0] + passedComponents.add(matched.split(' ')[0].trim()) + } + passedComponents = passedComponents.unique() + + for (component in inputManifest.components) { + if (failedComponents.contains(component.name)) { + println("Component ${component.name} failed, creating github issue") + exactComponentFailureMessage = getExactErrorMessage(failureMessages, component.name) + ghIssueBody = """***Received Error***: **${exactComponentFailureMessage}**. + ${component.name} failed during the distribution build for version: ${currentVersion}. + Please see build log at ${env.RUN_DISPLAY_URL}. + The failed build stage will be marked as unstable(!). Please see ./build.sh step for more details""".stripIndent() + createGithubIssue( + repoUrl: component.repository, + issueTitle: "[AUTOCUT] Distribution Build Failed for ${component.name}-${currentVersion}", + issueBody: ghIssueBody, + label: "autocut,v${currentVersion}" + ) + } + if (passedComponents.contains(component.name) && !failedComponents.contains(component.name)) { + println("Component ${component.name} passed, closing github issue") + ghIssueBody = """Closing the issue as the distribution build for ${component.name} has passed for version: **${currentVersion}**. + Please see build log at ${env.RUN_DISPLAY_URL}""".stripIndent() + closeGithubIssue( + repoUrl: component.repository, + issueTitle: "[AUTOCUT] Distribution Build Failed for ${component.name}-${currentVersion}", + closeComment: ghIssueBody, + label: "autocut,v${currentVersion}" + ) + } + sleep(time:3, unit:'SECONDS') + } +} + +def getExactErrorMessage(FailureMessage, componentName) { + for (message in FailureMessage) { + if (message.contains(componentName)) { + return(message) + } + } +}