Skip to content

Commit 29a8f2e

Browse files
Itai GendlerItai Gendler
authored andcommitted
Support showing logs of a workflows
1 parent e13bb04 commit 29a8f2e

File tree

6 files changed

+78
-25
lines changed

6 files changed

+78
-25
lines changed

codefresh.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,3 @@ steps:
3333
candidate: ${{build_step}}
3434
tag: ${{CF_SHORT_REVISION}}
3535
registry: "CFCR"
36-
37-
push_to_registry_branch:
38-
title: "Pushing image tagged with branch to registry"
39-
type: push
40-
candidate: ${{build_step}}
41-
tag: ${{CF_BRANCH}}

lib/interface/cli/commands/root/logs.cmd.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const debug = require('debug')('codefresh:cli:logs');
22
const Command = require('../../Command');
33
const _ = require('lodash');
44
const CFError = require('cf-errors');
5-
const { logs } = require('../../../../logic').api;
5+
const { log } = require('../../../../logic').api;
66

77

88
const run = new Command({
@@ -25,7 +25,7 @@ const run = new Command({
2525
const workflowId = argv.id;
2626
const follow = argv.f;
2727

28-
await logs.showWorkflowLogs(workflowId, follow);
28+
await log.showWorkflowLogs(workflowId, follow);
2929
// TODO fix this. its a workaround since something related to firebase in not properly closed
3030
process.exit(0);
3131
},

lib/interface/cli/commands/root/run.cmd.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@ const CFError = require('cf-errors');
55
const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general');
66
const { pipeline } = require('../../../../logic').api;
77
const ObjectID = require('mongodb').ObjectID;
8+
const { log } = require('../../../../logic').api;
9+
const { workflow } = require('../../../../logic').api;
810

911

1012
const run = new Command({
1113
root: true,
1214
command: 'run <id>',
13-
description: 'Run a pipeline',
15+
description: 'Run a pipeline and attach the created workflow logs.\nReturns an exist code according to the workflow finish status (Success: 0, Error: 1, Terminated: 2).',
1416
builder: (yargs) => {
1517
yargs
16-
.usage('Running a pipeline:\n' +
17-
'\n' +
18-
'1. Provide an explicit pipeline id\n' +
19-
'\n' +
20-
'2. Provide a pipeline name, repository owner and repository name \n')
2118
.positional('id', {
2219
describe: 'Pipeline id',
2320
})
@@ -49,8 +46,9 @@ const run = new Command({
4946
type: 'number',
5047
default: 1,
5148
})
52-
.option('f', {
53-
describe: 'Show and follow the logs of the created workflow',
49+
.option('detach', {
50+
alias: 'd',
51+
describe: 'Run pipeline and print workflow ID',
5452
});
5553

5654
crudFilenameOption(yargs, {
@@ -103,9 +101,34 @@ const run = new Command({
103101
}
104102

105103
_.forEach(executionRequests, async (request) => {
106-
const res = await pipeline.runPipelineById(request.pipelineId, request.options);
107-
console.log(res);
104+
const workflowId = await pipeline.runPipelineById(request.pipelineId, request.options);
105+
if (executionRequests.length === 1) {
106+
if (argv.detach) {
107+
console.log(workflowId);
108+
} else {
109+
await log.showWorkflowLogs(workflowId, true);
110+
const workflowInstance = await workflow.getWorkflowById(workflowId);
111+
switch (workflowInstance.getStatus()) {
112+
case 'success':
113+
process.exit(0);
114+
break;
115+
case 'error':
116+
process.exit(1);
117+
break;
118+
case 'terminated':
119+
process.exit(2);
120+
break;
121+
default:
122+
process.exit(100);
123+
break;
124+
}
125+
}
126+
} else {
127+
console.log(workflowId);
128+
}
108129
});
130+
131+
109132
},
110133
});
111134

lib/logic/api/helper.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const sendHttpRequest = async (httpOptions, authContext) => {
2626
printError('Forbidden error: You do not have permissions to perform this action');
2727
process.exit(1);
2828
}
29+
30+
throw err;
2931
}
3032
debug('Response:\n%O', response);
3133
return response;

lib/logic/api/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const image = require('./image');
55
const composition = require('./composition');
66
const environment = require('./environment');
77
const workflow = require('./workflow');
8-
const logs = require('./logs');
8+
const log = require('./log');
99

1010
module.exports = {
1111
user,
@@ -15,5 +15,5 @@ module.exports = {
1515
composition,
1616
environment,
1717
workflow,
18-
logs,
18+
log,
1919
};

lib/logic/api/logs.js renamed to lib/logic/api/log.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const { sendHttpRequest } = require('./helper');
66
const workflows = require('./workflow');
77
const Firebase = require('firebase');
88
const rp = require('request-promise');
9+
const logUpdate = require('log-update');
910

1011
const getFirebaseToken = async () => {
1112
const options = {
@@ -41,7 +42,7 @@ const printLogsFromJson = (steps) => {
4142
.join('=');
4243
console.log(`${prefixSuffix}\nStep: ${step.name}\n${prefixSuffix}`);
4344
_.forEach(step.logs, (log) => {
44-
console.log(log);
45+
process.stdout.write(log);
4546
});
4647
});
4748
};
@@ -64,8 +65,41 @@ const printCurrentFirebaseLogs = async (firebaseAuth, progressJobId) => {
6465
return promise;
6566
};
6667

67-
// TODO implement
68-
const printFollowFirebaseLogs = async (firebaseAuth, progressJobId) => { // eslint-disable-line
68+
69+
const printFollowFirebaseLogs = async (firebaseAuth, progressJobId) => {
70+
const promise = new Promise((resolve, reject) => {
71+
const jobIdRef = new Firebase(`${firebaseAuth.url}/build-logs/${progressJobId}`);
72+
73+
const errorCallback = (err) => {
74+
reject(new CFError({
75+
cause: err,
76+
message: 'Failed to get logs from firebase',
77+
}));
78+
};
79+
80+
jobIdRef.child('status')
81+
.on('value', (snapshot) => {
82+
const status = snapshot.val();
83+
if (['success', 'error', 'terminated'].includes(status)) {
84+
resolve();
85+
}
86+
}, errorCallback);
87+
88+
jobIdRef.child('steps')
89+
.on('child_added', (snapshot) => {
90+
const step = snapshot.val();
91+
const prefixSuffix = Array(step.name.length)
92+
.join('=');
93+
console.log(`${prefixSuffix}\nStep: ${step.name}\n${prefixSuffix}`);
94+
step.ref = snapshot.ref();
95+
step.ref.child('logs')
96+
.on('child_added', (snapshot) => {
97+
const log = snapshot.val();
98+
process.stdout.write(log);
99+
}, errorCallback);
100+
}, errorCallback);
101+
});
102+
return promise;
69103
};
70104

71105
const getProgressJob = async (workflowId) => {
@@ -84,8 +118,8 @@ const getProgressJob = async (workflowId) => {
84118
const showWorkflowLogsFromFirebase = async (progressJobId, follow) => {
85119
const firebaseAuth = await getFirebaseToken();
86120
await connectToFirebase(firebaseAuth);
87-
if (follow) { // eslint-disable-line
88-
// TODO implement
121+
if (follow) {
122+
await printFollowFirebaseLogs(firebaseAuth, progressJobId);
89123
} else {
90124
await printCurrentFirebaseLogs(firebaseAuth, progressJobId);
91125
}

0 commit comments

Comments
 (0)