Skip to content

Commit

Permalink
Group pi-gen stage logs
Browse files Browse the repository at this point in the history
  • Loading branch information
usimd committed Nov 6, 2024
1 parent 9b9106f commit de9c7df
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 22 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ jobs:
- run: npm test

- uses: codecov/codecov-action@v4
if: failure() || success()
with:
files: coverage/clover.xml,coverage/lcov.info
flags: unittests
token: ${{ secrets.CODECOV_TOKEN }}

- run: npm run lint

Expand Down
66 changes: 56 additions & 10 deletions __test__/pi-gen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,17 @@ describe('PiGen', () => {
)

it.each([
[false, 'no stage message', 'info', 0],
[true, 'no stage message', 'info', 1],
[false, '[00:00:00] stage message', 'info', 1],
[true, 'warning message', 'warning', 1],
[false, '#6 [1/3] FROM docker.io', 'warning', 0],
[true, '#7 [2/3] RUN', 'warning', 0],
[false, ' #6 [1/3] FROM docker.io', 'info', 0],
[true, ' #7 [2/3] RUN', 'info', 1]
['no stage message', false, 'info', 0],
['no stage message', true, 'info', 1],
['[00:00:00] stage message', false, 'info', 0],
['warning message', true, 'warning', 1],
['#6 [1/3] FROM docker.io', false, 'warning', 0],
['#7 [2/3] RUN', true, 'warning', 0],
[' #6 [1/3] FROM docker.io', false, 'info', 0],
[' #7 [2/3] RUN', true, 'info', 1]
])(
'handles log messages if verbose = %s',
(verbose, line, stream, nCalls) => {
'handles log message "%s" correctly if verbose = %s',
(line, verbose, stream, nCalls) => {
jest.spyOn(core, 'info').mockImplementation(s => {})
jest.spyOn(core, 'warning').mockImplementation(s => {})
mockPiGenDependencies()
Expand All @@ -248,6 +248,52 @@ describe('PiGen', () => {
}
)

it.each([
[['no stage message'], 0, 0, null],
[['[00:00:00] Begin stage-name'], 1, 0, ['stage-name']],
[['[00:00:00] End stage-name'], 0, 1, null]
])(
'opens and closes log groups according to pi-gen status messages',
(lines, startGroupCalls, endGroupCalls, startGroupValues) => {
jest.spyOn(core, 'startGroup').mockImplementation(_ => {})
jest.spyOn(core, 'endGroup').mockImplementation(() => null)
mockPiGenDependencies()

const piGenSut = new PiGen('pi-gen', {
...DEFAULT_CONFIG,
stageList: ['stage0']
})
lines.forEach(line => piGenSut.logOutput(line, false, 'info'))

if (startGroupCalls > 0) {
expect(core.startGroup).toHaveBeenCalledTimes(startGroupCalls)
startGroupValues?.forEach(groupName =>
expect(core.startGroup).toHaveBeenCalledWith(groupName)
)
}

if (endGroupCalls > 0) {
expect(core.endGroup).toHaveBeenCalledTimes(endGroupCalls)
}
}
)

it('closes still open log groups if build crashes', async () => {
jest.spyOn(fs, 'realpathSync').mockReturnValue('/pi-gen/stage0')
jest.spyOn(core, 'endGroup')
jest
.spyOn(exec, 'getExecOutput')
.mockImplementationOnce((cmdLine, args) =>
Promise.resolve({} as exec.ExecOutput)
)

const piGen = new PiGen('', {...DEFAULT_CONFIG, stageList: ['stage0']})
piGen.openLogGroups = 2
await piGen.build()

expect(core.endGroup).toHaveBeenCalledTimes(2)
})

it.each([
['none', [] as string[], undefined],
['xz', ['foo.img.xz', 'bar.img.xz'], 'foo.img.xz']
Expand Down
8 changes: 6 additions & 2 deletions src/pi-gen-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ export async function writeToFile(
: config[prop as keyof PiGenConfig]
}"`
)
.join('\n')
return fs.writeFile(file, configContent)

// We're adding this as a default to the config so that it's going to be
// picked up by pi-gen as well in order to reduce log volume
configContent.push('DEBIAN_FRONTEND=noninteractive')

return fs.writeFile(file, configContent.join('\n'))
}

export async function validateConfig(config: PiGenConfig): Promise<void> {
Expand Down
37 changes: 27 additions & 10 deletions src/pi-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import * as glob from '@actions/glob'
import {PiGenStages} from './pi-gen-stages'
import {PiGenConfig, writeToFile} from './pi-gen-config'
import path from 'path'
import * as colors from 'ansi-colors'

export class PiGen {
private configFilePath: string
private piGenBuildLogPattern = /^\s*\[(?:\d{2}:?){3}\]/gm
openLogGroups: number = 0

constructor(
private piGenDirectory: string,
Expand Down Expand Up @@ -66,10 +66,8 @@ export class PiGen {
)}`
)

return await exec.getExecOutput(
'"./build-docker.sh"',
['-c', this.configFilePath],
{
return await exec
.getExecOutput('"./build-docker.sh"', ['-c', this.configFilePath], {
cwd: this.piGenDirectory,
env: {
PIGEN_DOCKER_OPTS: dockerOpts,
Expand All @@ -81,8 +79,13 @@ export class PiGen {
},
silent: true,
ignoreReturnCode: true
}
)
})
.finally(() => {
while (this.openLogGroups > 0) {
core.endGroup()
this.openLogGroups--
}
})
}

async getLastImagePath(): Promise<string | undefined> {
Expand Down Expand Up @@ -171,9 +174,23 @@ export class PiGen {
logOutput(line: string, verbose: boolean, stream: 'info' | 'warning'): void {
const isPiGenStatusMessage = this.piGenBuildLogPattern.test(line)

if (verbose || isPiGenStatusMessage) {
line = isPiGenStatusMessage ? colors.bold(colors.unstyle(line)) : line

if (isPiGenStatusMessage) {
line = line
.replace(this.piGenBuildLogPattern, '')
.replace(`${process.env.GITHUB_WORKSPACE || ''}/`, '')
.replace(`${this.piGenDirectory}/`, '')
.trim()

if (line.includes('Begin')) {
line = line.replace('Begin', '').trim()
this.openLogGroups++
core.startGroup(line)
} else if (line.includes('End')) {
line = line.replace('End', '').trim()
this.openLogGroups--
core.endGroup()
}
} else if (stream == 'warning' || verbose) {
// Do not issue warning annotations for Docker BuildKit progress messages.
// No clue how to better suppress/redirect them for now.
stream === 'info' || line.match(/^\s*#\d+\s/m)
Expand Down

0 comments on commit de9c7df

Please sign in to comment.