UNPKG

3.19 kBJavaScriptView Raw
1const cli = require('heroku-cli-util')
2const Dyno = require('heroku-run').Dyno
3const co = require('co')
4const api = require('../../lib/heroku-api')
5const git = require('../../lib/git')
6const source = require('../../lib/source')
7const TestRun = require('../../lib/test-run')
8
9// Default command. Run setup, source profile.d scripts and open a bash session
10const SETUP_COMMAND = 'ci setup && eval $(ci env)'
11const COMMAND = `${SETUP_COMMAND} && bash`
12
13function* run (context, heroku) {
14 const coupling = yield api.pipelineCoupling(heroku, context.app)
15 const pipeline = coupling.pipeline
16 const pipelineRepository = yield api.pipelineRepository(heroku, pipeline.id)
17 const organization = pipelineRepository.organization &&
18 pipelineRepository.organization.name
19
20 const commit = yield git.readCommit('HEAD')
21 const sourceBlobUrl = yield cli.action('Preparing source', co(function* () {
22 return yield source.createSourceBlob(commit.ref, context, heroku)
23 }))
24
25 // Create test run and wait for it to transition to `debugging`
26 const testRun = yield cli.action('Creating test run', co(function* () {
27 const run = yield api.createTestRun(heroku, {
28 commit_branch: commit.branch,
29 commit_message: commit.message,
30 commit_sha: commit.ref,
31 pipeline: pipeline.id,
32 organization,
33 source_blob_url: sourceBlobUrl,
34 debug: true
35 })
36
37 return yield TestRun.waitForStates(['debugging', 'errored'], run, { heroku })
38 }))
39
40 if (testRun.status === 'errored') {
41 cli.exit(1, `Test run creation failed while ${testRun.error_state} with message "${testRun.message}"`)
42 }
43
44 const appSetup = yield api.appSetup(heroku, testRun.app_setup.id)
45 const noSetup = context.flags['no-setup']
46
47 const dyno = new Dyno({
48 heroku,
49 app: appSetup.app.id,
50 command: noSetup ? 'bash' : COMMAND,
51 'exit-code': true,
52 'no-tty': context.flags['no-tty'],
53 attach: true,
54 env: 'HEROKU_SUPPRESS_LOGGING=true',
55 size: context.flags.size,
56 showStatus: false
57 })
58
59 cli.log(`${noSetup ? 'Attaching' : 'Running setup and attaching'} to test dyno...`)
60
61 if (noSetup) {
62 cli.warn('Skipping test setup phase.')
63 cli.warn(`Run \`${SETUP_COMMAND}\``)
64 cli.warn('to execute a build and configure the environment')
65 }
66
67 try {
68 yield dyno.start()
69 } catch (err) {
70 if (err.exitCode) cli.exit(err.exitCode, err)
71 else throw err
72 }
73
74 yield cli.action(
75 'Cleaning up',
76 api.updateTestRun(heroku, testRun.id, {
77 status: 'cancelled',
78 message: 'debug run cancelled by Heroku CLI'
79 })
80 )
81}
82
83module.exports = {
84 topic: 'ci',
85 command: 'debug',
86 needsApp: true,
87 needsAuth: true,
88 description: 'opens an interactive test debugging session with the contents of the current directory',
89 help: `$ heroku ci:debug
90Preparing source... done
91Creating test run... done
92Running setup and attaching to test dyno...
93
94~ $
95`,
96 flags: [
97 {
98 name: 'no-setup',
99 hasValue: false,
100 description: 'start test dyno without running test-setup'
101 },
102 {
103 name: 'size',
104 char: 's',
105 hasValue: true,
106 description: 'dyno size'
107 }
108 ],
109 run: cli.command(co.wrap(run))
110}