Skip to content

Commit

Permalink
fix(image): account for stderr when looking for an image sha
Browse files Browse the repository at this point in the history
in the case the progress output is set to plain, the build output is
written to stderr rather than stdout. This updates the logic to check
each line with a regex starting from the end of the output

Fixes: #46
  • Loading branch information
esatterwhite committed Feb 4, 2024
1 parent 270b413 commit e9f6a3b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 10 deletions.
18 changes: 14 additions & 4 deletions lib/docker/image.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use strict'

const os = require('os')
const path = require('path')
const crypto = require('crypto')
const execa = require('execa')
const array = require('../lang/array/index.js')
const SHA_REGEX = /(?:writing image\s)?[^@](?:sha\d{3}):(?<sha>\w+)/i

class Image {
constructor(opts) {
Expand Down Expand Up @@ -160,10 +162,18 @@ class Image {
const stream = execa('docker', this.build_cmd)
stream.stdout.pipe(process.stdout)
stream.stderr.pipe(process.stderr)
const {stdout} = await stream
const [_, sha] = stdout.split(':')
this.sha = sha.substring(0, 12)
return this.sha
const {stdout, stderr} = await stream
const lines = (stdout || stderr).split(os.EOL)
const len = lines.length - 1

for (let x = len; x >= 0; x--) {
const line = lines[x]
const match = SHA_REGEX.exec(line)
if (match) {
this.sha = match.groups.sha.substring(0, 12)
return this.sha
}
}
}

async tag(tag, push = true) {
Expand Down
2 changes: 1 addition & 1 deletion test/fixture/docker/Dockerfile.publish
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM debian:buster-slim
FROM debian:bullseye-slim
COPY . /opt/whizbang
WORKDIR /opt/whizbang
CMD ["echo", "$PWD"]
67 changes: 62 additions & 5 deletions test/integration/prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ test('steps::prepare', async (t) => {
tt.equal(image.opts.args.get('MAJOR_TEMPLATE'), '2', 'MAJOR_TEMPLATE value')
tt.equal(image.opts.args.get('GIT_REF'), 'abacadaba', 'GIT_REF value')
tt.match(image.opts.args.get('BUILD_DATE'), DATE_REGEX, 'BUILD_DATE value')
tt.match(
image.opts.flags.get('TAG_TEMPLATE')
, ['v2.1.2']
, 'TAG_TEMPLATE stored as a flag'
)
tt.equal(image.context, path.join(context.cwd, config.context), 'docker context path')

const {stdout} = await execa('docker', [
Expand All @@ -85,4 +80,66 @@ test('steps::prepare', async (t) => {
])
tt.equal(stdout, build_id, 'build image fully built')
})

t.test('build image created - progress plain', async (tt) => {
const build_id = crypto.randomBytes(5).toString('hex')
const context = {
env: {
...process.env
, DOCKER_REGISTRY_USER: 'iamweasel'
, DOCKER_REGISTRY_PASSWORD: 'secretsquirrel'
}
, cwd: fixturedir
, nextRelease: {
version: '2.1.2'
, gitTag: 'v2.1.2'
, gitHead: 'abacadaba'
}
, logger: {
success: sinon.stub()
, info: sinon.stub()
, debug: sinon.stub()
, fatal: sinon.stub()
}
}

const config = await buildConfig(build_id, {
dockerRegistry: DOCKER_REGISTRY_HOST
, dockerProject: 'docker-prepare'
, dockerImage: 'alternate'
, dockerBuildQuiet: false
, dockerBuildFlags: {
progress: 'plain'
, 'no-cache': null
}
, dockerArgs: {
MY_VARIABLE: '1'
, TAG_TEMPLATE: '{{git_tag}}'
, MAJOR_TEMPLATE: '{{major}}'
, GIT_REF: '{{git_sha}}'
, BUILD_DATE: '{{now}}'
}
, dockerFile: 'docker/Dockerfile.prepare'
, dockerContext: 'docker'
}, context)

const image = await prepare(config, context)

tt.on('end', () => {
image.clean()
})

tt.equal(image.opts.args.get('TAG_TEMPLATE'), 'v2.1.2', 'TAG_TEMPLATE value')
tt.equal(image.opts.args.get('MAJOR_TEMPLATE'), '2', 'MAJOR_TEMPLATE value')
tt.equal(image.opts.args.get('GIT_REF'), 'abacadaba', 'GIT_REF value')
tt.match(image.opts.args.get('BUILD_DATE'), DATE_REGEX, 'BUILD_DATE value')
tt.equal(image.context, path.join(context.cwd, config.context), 'docker context path')
tt.equal(image.id.length, 12, 'image sha set to 12 char value')

const {stdout} = await execa('docker', [
'images', image.name
, '-q', '--format={{ .Tag }}'
])
tt.equal(stdout, build_id, 'build image fully built')
})
}).catch(threw)

0 comments on commit e9f6a3b

Please sign in to comment.