Skip to content

Commit

Permalink
Add caching of pi-gen artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
usimd committed Nov 7, 2024
1 parent b727b4a commit 62f3a7b
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 140 deletions.
1 change: 1 addition & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ jobs:
pubkey-ssh-first-user: ${{ env.CONFIG_PUBLIC_KEY }}
increase-runner-disk-size: ${{ github.event_name != 'workflow_dispatch' || inputs.increase-runner-disk }}
apt-proxy: http://172.17.0.1:9999
enable-pigen-cache: true

- name: Move APT cache
continue-on-error: true
Expand Down
39 changes: 4 additions & 35 deletions __test__/actions.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as core from '@actions/core'
import {DEFAULT_CONFIG} from '../src/pi-gen-config'
import * as actions from '../src/actions'
import {removeContainer} from '../src/remove-container'
import {build} from '../src/build'
import {removeRunnerComponents} from '../src/increase-runner-disk-size'
import * as removeContainer from '../src/remove-container'

jest.mock('../src/configure', () => ({
configure: jest.fn().mockReturnValue(DEFAULT_CONFIG)
Expand All @@ -29,28 +28,11 @@ describe('Actions', () => {
it('should only increase disk space if requested', async () => {
jest.spyOn(core, 'getBooleanInput').mockReturnValueOnce(true)

await actions.piGen()
await actions.build()

expect(removeRunnerComponents).toHaveBeenCalled()
})

it('does not run build function twice but invokes cleanup', async () => {
jest
.spyOn(core, 'getState')
.mockReturnValueOnce('')
.mockReturnValueOnce('true')
.mockReturnValueOnce('true')
process.env['INPUT_INCREASE-RUNNER-DISK-SIZE'] = 'false'

// expect build here
await actions.run()
// expect cleanup here
await actions.run()

expect(build).toHaveBeenCalledTimes(1)
expect(removeContainer).toHaveBeenCalledTimes(1)
})

const errorMessage = 'any error'
it.each([new Error(errorMessage), errorMessage])(
'should catch errors thrown during build and set build safely as failed',
Expand All @@ -61,32 +43,19 @@ describe('Actions', () => {
})
jest.spyOn(core, 'setFailed')

await expect(actions.piGen()).resolves.not.toThrow()
await expect(actions.build()).resolves.not.toThrow()
expect(core.setFailed).toHaveBeenLastCalledWith(errorMessage)
}
)

it.each([new Error(errorMessage), errorMessage])(
'should gracefully catch errors thrown during cleanup and emit a warning message',
async error => {
jest.spyOn(core, 'getState').mockImplementation(name => {
throw error
})
jest.spyOn(removeContainer, 'removeContainer').mockRejectedValue(error)
jest.spyOn(core, 'warning')

await expect(actions.cleanup()).resolves.not.toThrow()
expect(core.warning).toHaveBeenLastCalledWith(errorMessage)
}
)

describe('cleanup', () => {
it.each(['', 'true'])(
'tries to remove container only if build has started = %s',
async buildStarted => {
jest.spyOn(core, 'getState').mockReturnValueOnce(buildStarted)
await actions.cleanup()
expect(removeContainer).toHaveBeenCalledTimes(buildStarted ? 1 : 0)
}
)
})
})
3 changes: 2 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ inputs:
This shall increase the available disk space so that also large images can be compiled on a free GHA runner (benchmark is the full image including a
desktop environment).
If any packages are missing during the build consider adding them to the `extra-host-dependencies` list.
enable-pigen-cache:
description: Enables caching of pi-gen work artifacts to GitHub action cache to speed up repetitive builds.
required: false
default: false
pi-gen-dir:
Expand All @@ -172,7 +174,6 @@ outputs:

runs:
using: node20
pre: dist/pre.js
main: dist/index.js
post: dist/post.js

Expand Down
115 changes: 89 additions & 26 deletions package-lock.json

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

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
"scripts": {
"build": "tsc",
"lint": "eslint src/**/*.ts",
"package": "npm run package-pre && npm run package-main && npm run package-post",
"package": "npm run package-main && npm run package-post",
"package-main": "ncc build src/main.ts -m --no-source-map-register --license licenses.txt",
"package-pre": "ncc build src/pre.ts -m --no-source-map-register --out dist/pre && move-file dist/pre/index.js dist/pre.js",
"package-post": "ncc build src/post.ts -m --no-source-map-register --out dist/post && move-file dist/post/index.js dist/post.js",
"test": "jest",
"all": "npm run build && npm run format && npm run lint && npm test && npm run package && npm run update-readme",
Expand Down Expand Up @@ -48,6 +47,7 @@
"@types/jest": "29.5.14",
"@types/js-yaml": "4.0.9",
"@types/node": "20.17.5",
"@types/object-hash": "^3.0.6",
"@types/semver": "7.5.8",
"@types/tmp": "0.2.6",
"@typescript-eslint/eslint-plugin": "7.18.0",
Expand All @@ -63,6 +63,7 @@
"jest-mock-extended": "3.0.7",
"js-yaml": "4.1.0",
"markdown-replace-section": "0.4.0",
"move-file-cli": "3.0.0",
"prettier": "3.3.3",
"semver": "7.6.3",
"ts-jest": "29.2.5",
Expand Down
38 changes: 11 additions & 27 deletions src/actions.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import * as core from '@actions/core'
import {Cache} from './cache'
import {configure} from './configure'
import {installHostDependencies} from './install-dependencies'
import {build} from './build'
import {build as piGenBuild} from './build'
import {clonePigen} from './clone-pigen'
import {removeContainer} from './remove-container'
import {removeRunnerComponents} from './increase-runner-disk-size'
import {Cache} from './cache'

const piGenBuildStartedState = 'pi-gen-build-started'
const cache = new Cache()

export async function piGen(): Promise<void> {
export async function build(): Promise<void> {
try {
// Need to force color output for chalk, until https://github.com/actions/runner/issues/241 is resolved.
// See also https://github.com/chalk/supports-color/issues/106
Expand Down Expand Up @@ -40,39 +37,26 @@ export async function piGen(): Promise<void> {
core.getInput('extra-host-modules'),
piGenDirectory
)

core.saveState(piGenBuildStartedState, true)
await build(piGenDirectory, userConfig)
await piGenBuild(piGenDirectory, userConfig)
} catch (error) {
core.setFailed((error as Error)?.message ?? error)
}
}

export async function cleanup(): Promise<void> {
try {
if (core.getState(piGenBuildStartedState)) {
await removeContainer('pigen_work')
} else {
core.info('No build started, nothing to clean')
}
await removeContainer('pigen_work')
} catch (error) {
core.warning((error as Error)?.message ?? error)
}
}

export async function run(): Promise<void> {
if (core.getState('main-executed')) {
await cleanup()
} else {
core.saveState('main-executed', true)
await piGen()
}
}

export async function restoreCache(): Promise<void> {
await cache.restoreCache()
}
export async function restoreCache(): Promise<void> {}

export async function saveCache(): Promise<void> {
await cache.saveCache()
if (core.getBooleanInput('enable-pigen-cache')) {
core.startGroup('Cache pi-gen container')
const cache = new Cache()
cache.cacheContainer()
}
}
Loading

0 comments on commit 62f3a7b

Please sign in to comment.