diff --git a/incrementals-publisher/index.js b/incrementals-publisher/index.js index c832420..1d5ea1f 100644 --- a/incrementals-publisher/index.js +++ b/incrementals-publisher/index.js @@ -48,7 +48,7 @@ module.exports = async (context, data) => { context.log.error('Misplaced build_url', buildUrl, JENKINS_HOST); return failRequest(context, 'This build_url is not supported'); } - if (!buildUrl.substring(JENKINS_HOST.length).match('(job/[a-zA-Z0-9._-]+/)+[0-9]+/') || buildUrl.includes('/../') || buildUrl.includes('/./')) { + if (!buildUrl.substring(JENKINS_HOST.length).match('^(job/[a-zA-Z0-9._-]+/)+[0-9]+/$') || buildUrl.includes('/../') || buildUrl.includes('/./')) { context.log.error('Malformed build_url', buildUrl); return failRequest(context, 'This build_url is malformed'); } diff --git a/incrementals-publisher/lib/github.js b/incrementals-publisher/lib/github.js index 488fb44..59904ca 100644 --- a/incrementals-publisher/lib/github.js +++ b/incrementals-publisher/lib/github.js @@ -11,6 +11,7 @@ module.exports = { commitExists: async (owner, repo, sha) => { let github = new GitHubApi(); /* The function must have this Application Setting already created */ + // TODO a failure here results in UnhandledPromiseRejectionWarning but the function continues github.authenticate({ type: 'oauth', token: GITHUB_TOKEN diff --git a/incrementals-publisher/lib/pipeline.js b/incrementals-publisher/lib/pipeline.js index 072cf3d..b4306f3 100644 --- a/incrementals-publisher/lib/pipeline.js +++ b/incrementals-publisher/lib/pipeline.js @@ -13,13 +13,13 @@ module.exports = { */ processBuildMetadata: (metadata) => { let response = {}; - - metadata.actions.forEach((action) => { - if (action._class === 'jenkins.scm.api.SCMRevisionAction') { - response.hash = action.revision.hash || action.revision.pullHash; - } - }); - + if (metadata.actions) { + metadata.actions.forEach((action) => { + if (action._class === 'jenkins.scm.api.SCMRevisionAction') { + response.hash = action.revision.hash || action.revision.pullHash; + } + }); + } return response; }, diff --git a/incrementals-publisher/test/index-test.js b/incrementals-publisher/test/index-test.js index 9cd1eb1..3b5baca 100644 --- a/incrementals-publisher/test/index-test.js +++ b/incrementals-publisher/test/index-test.js @@ -53,6 +53,7 @@ describe('Handling incremental publisher webhook events', () => { 'https://ci.jenkins.io/job/hack%79/123/', 'https://ci.jenkins.io/job/../123/', 'https://ci.jenkins.io/job/./123/', + 'https://ci.jenkins.io/job/ok/123//', ]) { it(u + ' should return a 400', () => { data.body.build_url = u; diff --git a/incrementals-publisher/test/pipeline-test.js b/incrementals-publisher/test/pipeline-test.js index 795c058..12ca256 100644 --- a/incrementals-publisher/test/pipeline-test.js +++ b/incrementals-publisher/test/pipeline-test.js @@ -52,6 +52,94 @@ describe('The Pipeline helpers', () => { const value = pipeline.processBuildMetadata(metadata); assert.equal(value.hash, "abc131cc3bf56309a05b3fe8b086b265d14f2a61"); }); + + let metadata2 = { // https://ci.jenkins.io/job/Core/job/jenkins/job/master/888/api/json?tree=actions[revision[hash,pullHash]]&pretty + "_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun", + "actions" : [ + { + "_class" : "hudson.model.CauseAction" + }, + { + "_class" : "jenkins.metrics.impl.TimeInQueueAction" + }, + { + + }, + { + "_class" : "jenkins.scm.api.SCMRevisionAction", + "revision" : { + "_class" : "jenkins.plugins.git.AbstractGitSCMSource$SCMRevisionImpl" + } + }, + { + + }, + { + "_class" : "hudson.plugins.git.util.BuildData" + }, + { + "_class" : "hudson.plugins.git.GitTagAction" + }, + { + + }, + { + "_class" : "hudson.plugins.git.util.BuildData" + }, + { + "_class" : "org.jenkinsci.plugins.workflow.cps.EnvActionImpl" + }, + { + "_class" : "hudson.plugins.git.util.BuildData" + }, + { + + }, + { + + }, + { + "_class" : "hudson.tasks.junit.TestResultAction" + }, + { + + }, + { + + }, + { + + }, + { + + }, + { + + }, + { + + }, + { + "_class" : "org.jenkinsci.plugins.workflow.job.views.FlowGraphAction" + }, + { + + }, + { + + } + ] + }; + + it('should return no hash', () => { + const value = pipeline.processBuildMetadata(metadata2); + assert.equal(value.hash, null); + }); + + it('gracefully tolerates lack of any authentication', () => { + const value = pipeline.processBuildMetadata({}); + assert.equal(value.hash, null); + }); }); describe('getBuildApiUrl', () => {