Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding container image #44

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ inputs:
save-always:
default: "false"
description: "Run the post step to save the cache even if another step before fails"
utility-image:
default: "ghcr.io/containerd/busybox:latest"
description: "The container image to use for injecting and extracting the cache"
runs:
using: 'node20'
main: 'dist/index.js'
Expand Down
19 changes: 12 additions & 7 deletions dist/index.js

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

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions src/extract-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import { CacheOptions, Opts, getCacheMap, getMountArgsString, getTargetPath } from './opts.js';
import { run, runPiped } from './run.js';

async function extractCache(cacheSource: string, cacheOptions: CacheOptions, scratchDir: string) {
async function extractCache(cacheSource: string, cacheOptions: CacheOptions, scratchDir: string, containerImage: string) {
// Prepare Timestamp for Layer Cache Busting
const date = new Date().toISOString();

Expand All @@ -15,7 +15,7 @@ async function extractCache(cacheSource: string, cacheOptions: CacheOptions, scr
const mountArgs = getMountArgsString(cacheOptions);

const dancefileContent = `
FROM busybox:1
FROM ${containerImage}
COPY buildstamp buildstamp
RUN --mount=${mountArgs} \
mkdir -p /var/dance-cache/ \
Expand Down Expand Up @@ -54,9 +54,10 @@ export async function extractCaches(opts: Opts) {

const cacheMap = getCacheMap(opts);
const scratchDir = opts['scratch-dir'];
const containerImage = opts['utility-image'];

// Extract Caches for each source-target pair
for (const [cacheSource, cacheOptions] of Object.entries(cacheMap)) {
await extractCache(cacheSource, cacheOptions, scratchDir);
await extractCache(cacheSource, cacheOptions, scratchDir, containerImage);
}
}
7 changes: 4 additions & 3 deletions src/inject-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CacheOptions, Opts, getCacheMap, getMountArgsString, getTargetPath, get
import { run } from './run.js';
import { notice } from '@actions/core';

async function injectCache(cacheSource: string, cacheOptions: CacheOptions, scratchDir: string) {
async function injectCache(cacheSource: string, cacheOptions: CacheOptions, scratchDir: string, containerImage: string) {
// Clean Scratch Directory
await fs.rm(scratchDir, { recursive: true, force: true });
await fs.mkdir(scratchDir, { recursive: true });
Expand All @@ -29,7 +29,7 @@ async function injectCache(cacheSource: string, cacheOptions: CacheOptions, scra

// Prepare Dancefile to Access Caches
const dancefileContent = `
FROM busybox:1
FROM ${containerImage}
COPY buildstamp buildstamp
RUN --mount=${mountArgs} \
--mount=type=bind,source=.,target=/var/dance-cache \
Expand All @@ -54,9 +54,10 @@ RUN --mount=${mountArgs} \
export async function injectCaches(opts: Opts) {
const cacheMap = getCacheMap(opts);
const scratchDir = opts['scratch-dir'];
const containerImage = opts['utility-image'];

// Inject Caches for each source-target pair
for (const [cacheSource, cacheOptions] of Object.entries(cacheMap)) {
await injectCache(cacheSource, cacheOptions, scratchDir);
await injectCache(cacheSource, cacheOptions, scratchDir, containerImage);
}
}
5 changes: 4 additions & 1 deletion src/opts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type Opts = {
"cache-map": string
"scratch-dir": string
"skip-extraction": boolean
"utility-image": string
help: boolean
/** @deprecated Use `cache-map` instead */
"cache-source"?: string
Expand All @@ -20,9 +21,10 @@ export function parseOpts(args: string[]): mri.Argv<Opts> {
"scratch-dir": getInput("scratch-dir") || "scratch",
"skip-extraction": (getInput("skip-extraction") || "false") === "true",
"extract": process.env[`STATE_POST`] !== undefined,
"utility-image": getInput("utility-image") || "ghcr.io/containerd/busybox:latest",
"help": false,
},
string: ["cache-map", "scratch-dir", "cache-source", "cache-target"],
string: ["cache-map", "scratch-dir", "cache-source", "cache-target", "utility-image"],
boolean: ["skip-extraction", "help", "extract"],
alias: {
"help": ["h"],
Expand All @@ -49,6 +51,7 @@ Options:
--cache-map The map of actions source paths to container destination paths or mount arguments
--scratch-dir Where the action is stores some temporary files for its processing. Default: 'scratch'
--skip-extraction Skip the extraction of the cache from the docker container
--utility-image The container image to use for injecting and extracting the cache. Default: 'ghcr.io/containerd/busybox:latest'
--help Show this help
`);
}
Expand Down
26 changes: 22 additions & 4 deletions tests/opts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ test('parseOpts with no arguments', () => {
"skip-extraction": false,
"extract": false,
"h": false,
"help": false
"help": false,
"utility-image": "ghcr.io/containerd/busybox:latest"
})
})

Expand All @@ -23,7 +24,8 @@ test('parseOpts with cache-map argument', () => {
"skip-extraction": false,
"extract": false,
"h": false,
"help": false
"help": false,
"utility-image": "ghcr.io/containerd/busybox:latest"
})
})

Expand All @@ -38,7 +40,22 @@ test('parseOpts with deprecated cache-source and cache-target arguments', () =>
"h": false,
"help": false,
"cache-source": 'source',
"cache-target": 'target'
"cache-target": 'target',
"utility-image": "ghcr.io/containerd/busybox:latest"
})
})

test('parseOpts with utility-image argument', () => {
const opts = parseOpts(['--utility-image', 'alpine:1'])
expect(opts).toEqual({
"_": [],
"cache-map": '{}',
"scratch-dir": "scratch",
"skip-extraction": false,
"extract": false,
"h": false,
"help": false,
"utility-image": "alpine:1"
})
})

Expand All @@ -52,6 +69,7 @@ test('parseOpts with help argument', () => {
"extract": false,
"h": true,
"help": true,
"utility-image": "ghcr.io/containerd/busybox:latest"
})
})

Expand Down Expand Up @@ -131,4 +149,4 @@ test('getGID with object with gid', () => {
const cacheOptions = { target: 'targetPath', shared: true, id: 1, gid: 1000 }
const gid = getGID(cacheOptions)
expect(gid).toBe('1000')
})
})
Loading