Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
estherk0 committed Jan 4, 2021
1 parent 98eedc2 commit b6e76b9
Show file tree
Hide file tree
Showing 1,368 changed files with 562,004 additions and 0 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# jenkins-trigger-action
Trigger jenkins job in github action and wait for job completion.

## Usage
### Generate API token for Jenkins API
Please see [How to get the API Token for Jenkins](https://stackoverflow.com/questions/45466090/how-to-get-the-api-token-for-jenkins)
> 1. Log in Jenkins.
> 2. Click you name (upper-right corner).
> 3. Click Configure (left-side menu).
> 4. Use "Add new Token" button to generate a new one then name it.
> 5. You must copy the token when you generate it as you cannot view the token afterwards.
> 6. Revoke old tokens when no longer needed.
### Inputs
| name | required | description |
| ---- | -------- | ----------- |
| url | `true` | Jenkins full URL including http/https protocol |
| user_name | `true` | User name of Jenkins |
| api_token | `true` | Jenkins API token |
| job_name | `true` | Jenkins job name |
| parameter | false | Job parameter in JSON format. ex) {"param1":"value1"} |
| wait | false | Set true as default. Waiting for job completion or not |
| timeout | false | Set 600 seconds as default. Timeout (seconds) for github action. |

### Example
```yaml
- name: Trigger jenkins job
uses: jabbukka/jenkins-trigger@master
with:
url: ${{ secrets.JENKINS_URL }}
user_name: ${{ secrets.JENKINS_USER }}
api_token: ${{ secrets.JENKINS_TOKEN }}
wait: "true"
timeout: "1000"
```
33 changes: 33 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Jenkins Job Trigger'
description: 'Trigger a Jenkins job'
branding:
icon: 'terminal'
color: 'green'
inputs:
url:
description: 'Jenkins full URL including http/https protocol'
required: true
user_name:
description: 'User name of Jenkins'
required: true
api_token:
description: 'Jenkins API token'
required: true
job_name:
description: 'Job name'
required: true
parameter:
description: 'Job parameter in JSON format. ex) {"param1":"value1"} '
required: false
wait:
description: 'Waiting for job completion or not'
required: false
default: "true"
timeout:
description: 'Timeout (seconds) for github action. Set 600s as default'
required: false
default: "600"

runs:
using: 'node12'
main: 'index.js'
101 changes: 101 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const request = require('request');
const core = require('@actions/core');

// create auth token for Jenkins API
const API_TOKEN = Buffer.from(`${core.getInput('user_name')}:${core.getInput('api_token')}`).toString('base64');

let timer = setTimeout(() => {
core.setFailed("Job Timeout");
core.error("Exception Error: Timed out");
}, (Number(core.getInput('timeout')) * 1000));

const sleep = (seconds) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, (seconds * 1000));
});
};

async function requestJenkinsJob(jobName, params) {
const req = {
method: 'POST',
url: `https://jenkins.hanu-ci.io/job/${jobName}/buildWithParameters`,
form: params,
headers: {
'Authorization': `Basic ${API_TOKEN}`
}
}
await new Promise((resolve, reject) => request(req)
.on('response', (res) => {
core.info(`>>> Job is started!`);
resolve();
})
.on("error", (err) => {
core.setFailed(err);
core.error(JSON.stringify(err));
clearTimeout(timer);
reject();
})
);
}

async function getJobStatus(jobName) {
const req = {
method: 'get',
url: `http://jenkins.hanu-ci.io/job/${jobName}/lastBuild/api/json`,
headers: {
'Authorization': `Basic ${API_TOKEN}`
}
}
return new Promise((resolve, reject) =>
request(req, (err, res, body) => {
if (err) {
clearTimeout(timer);
reject(err);
}
resolve(JSON.parse(body));
})
);
}
async function waitJenkinsJob(jobName, timestamp) {
core.info(`>>> Waiting for "${jobName}" ...`);
while (true) {
let data = await getJobStatus(jobName);
if (data.timestamp < timestamp) {
core.info(`>>> Job is not started yet... Wait 5 seconds more...`)
} else if (data.result == "SUCCESS") {
core.info(`>>> Job "${data.fullDisplayName}" successfully completed!`);
break;
} else if (data.result == "FAILURE" || data.result == "ABORTED") {
throw new Error(`Failed job ${data.fullDisplayName}`);
} else {
core.info(`>>> Current Duration: ${data.duration}. Expected: ${data.estimatedDuration}`);
}
await sleep(5); // API call interval
}
}

async function main() {
try {
let params = {};
let startTs = + new Date();
let jobName = core.getInput('job_name');
if (core.getInput('parameter')) {
param = JSON.parse(core.getInput('parameter'));
}
// POST API call
await requestJenkinsJob(jobName, params);

// Waiting for job completion
if (core.getInput('wait' == 'true')) {
await waitJenkinsJob(jobName, startTs);
}
} catch (err) {
core.setFailed(err.message);
core.error(err.message);
} finally {
clearTimeout(timer);
}
}

process.env.NODE_TLS_REJECT_UNAUTHORIZED="0";
main();
7 changes: 7 additions & 0 deletions node_modules/.bin/ncc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

160 changes: 160 additions & 0 deletions node_modules/.bin/semver

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b6e76b9

Please sign in to comment.