Skip to content

Commit cd5049a

Browse files
committed
Support downloading binaries from docker images
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
1 parent 810b53a commit cd5049a

File tree

5 files changed

+185
-19
lines changed

5 files changed

+185
-19
lines changed

__tests__/context.test.ts

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ describe('getInputs', () => {
2121
['set-host', 'false'],
2222
]),
2323
{
24-
version: 'v24.0.8',
25-
channel: '',
24+
source: {
25+
type: 'archive',
26+
version: 'v24.0.8',
27+
channel: 'stable'
28+
},
2629
context: '',
2730
daemonConfig: '',
2831
setHost: false
@@ -38,8 +41,11 @@ describe('getInputs', () => {
3841
['set-host', 'false'],
3942
]),
4043
{
41-
version: 'v24.0.0-rc.4',
42-
channel: 'test',
44+
source: {
45+
type: 'archive',
46+
version: 'v24.0.0-rc.4',
47+
channel: 'test'
48+
},
4349
context: 'foo',
4450
daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`,
4551
setHost: false
@@ -51,13 +57,100 @@ describe('getInputs', () => {
5157
['set-host', 'true'],
5258
]),
5359
{
54-
version: 'latest',
55-
channel: '',
60+
source: {
61+
type: 'archive',
62+
version: 'latest',
63+
channel: 'stable',
64+
},
5665
context: '',
5766
daemonConfig: '',
5867
setHost: true
5968
} as context.Inputs
60-
]
69+
],
70+
[
71+
3,
72+
new Map<string, string>([
73+
['version', 'type=image,tag=master'],
74+
['context', 'foo'],
75+
['daemon-config', `{"debug":true,"features":{"containerd-snapshotter":true}}`],
76+
['set-host', 'false'],
77+
]),
78+
{
79+
source: {
80+
type: 'image',
81+
tag: 'master',
82+
},
83+
context: 'foo',
84+
daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`,
85+
setHost: false
86+
} as context.Inputs
87+
],
88+
[
89+
4,
90+
new Map<string, string>([
91+
['version', 'type=image'],
92+
['set-host', 'false'],
93+
]),
94+
{
95+
source: {
96+
type: 'image',
97+
tag: 'latest',
98+
},
99+
context: '',
100+
daemonConfig: '',
101+
setHost: false
102+
} as context.Inputs
103+
],
104+
[
105+
5,
106+
new Map<string, string>([
107+
['version', 'type=archive'],
108+
['set-host', 'false'],
109+
]),
110+
{
111+
source: {
112+
type: 'archive',
113+
version: 'latest',
114+
channel: 'stable',
115+
},
116+
setHost: false,
117+
context: '',
118+
daemonConfig: '',
119+
} as context.Inputs
120+
],
121+
[
122+
6,
123+
new Map<string, string>([
124+
['version', 'version=v27.2.0,channel=test'],
125+
['set-host', 'false'],
126+
]),
127+
{
128+
source: {
129+
type: 'archive',
130+
version: 'v27.2.0',
131+
channel: 'test',
132+
},
133+
setHost: false,
134+
context: '',
135+
daemonConfig: '',
136+
} as context.Inputs
137+
],
138+
[
139+
7,
140+
new Map<string, string>([
141+
['version', 'type=image,tag=27.2.1'],
142+
['set-host', 'false'],
143+
]),
144+
{
145+
source: {
146+
type: 'image',
147+
tag: '27.2.1',
148+
},
149+
setHost: false,
150+
context: '',
151+
daemonConfig: '',
152+
} as context.Inputs
153+
],
61154
])(
62155
'[%d] given %p as inputs, returns %p',
63156
async (num: number, inputs: Map<string, string>, expected: context.Inputs) => {

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/context.ts

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,96 @@
11
import * as core from '@actions/core';
2+
import {InstallSource} from '@docker/actions-toolkit/lib/docker/install';
3+
import {parse} from 'csv-parse/sync';
24

35
export interface Inputs {
4-
version: string;
5-
channel: string;
6+
source: InstallSource;
67
daemonConfig?: string;
78
context: string;
89
setHost: boolean;
910
}
1011

1112
export function getInputs(): Inputs {
13+
const rawVersion = core.getInput('version') || 'latest';
14+
const source = parseSource(rawVersion);
15+
const channel = core.getInput('channel');
16+
if (channel && source.type === 'archive') {
17+
source.channel = channel;
18+
}
19+
1220
return {
13-
version: core.getInput('version') || 'latest',
14-
channel: core.getInput('channel'),
21+
source: source,
1522
daemonConfig: core.getInput('daemon-config'),
1623
context: core.getInput('context'),
1724
setHost: core.getBooleanInput('set-host')
1825
};
1926
}
27+
28+
function parseSource(input: string): InstallSource {
29+
let [type, version, channel, tag] = ['archive', 'latest', 'stable', 'latest'];
30+
31+
const fields = parse(input, {
32+
relaxColumnCount: true,
33+
skipEmptyLines: true
34+
})[0];
35+
for (const field of fields) {
36+
const parts = field
37+
.toString()
38+
.split(/(?<=^[^=]+?)=/)
39+
.map(item => item.trim());
40+
41+
switch (parts[0]) {
42+
case 'type':
43+
type = parts[1];
44+
break;
45+
case 'version':
46+
version = parts[1];
47+
break;
48+
case 'channel':
49+
channel = parts[1];
50+
break;
51+
case 'tag':
52+
tag = parts[1];
53+
break;
54+
default:
55+
if (fields.length === 1) {
56+
version = parts[0];
57+
break;
58+
}
59+
throw new Error(`Invalid field: ${parts[0]}`);
60+
}
61+
}
62+
63+
if (!type) {
64+
throw new Error(`Invalid type: ${type}`);
65+
}
66+
if (!channel) {
67+
throw new Error(`Invalid channel: ${channel}`);
68+
}
69+
if (!version) {
70+
throw new Error(`Invalid version: ${version}`);
71+
}
72+
if (!tag) {
73+
throw new Error(`Invalid tag: ${tag}`);
74+
}
75+
76+
let src: InstallSource;
77+
switch (type) {
78+
case 'archive':
79+
src = {
80+
type: 'archive',
81+
version: version,
82+
channel: channel
83+
};
84+
break;
85+
case 'image':
86+
src = {
87+
type: 'image',
88+
tag: tag
89+
};
90+
break;
91+
default:
92+
throw new Error(`Invalid version: ${input}`);
93+
}
94+
95+
return src;
96+
}

src/main.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,12 @@ actionsToolkit.run(
2121

2222
const install = new Install({
2323
runDir: runDir,
24-
source: {
25-
type: 'archive',
26-
version: input.version,
27-
channel: input.channel || 'stable'
28-
},
24+
source: input.source,
2925
contextName: input.context || 'setup-docker-action',
3026
daemonConfig: input.daemonConfig
3127
});
3228
let toolDir;
33-
if (!(await Docker.isAvailable()) || input.version) {
29+
if (!(await Docker.isAvailable()) || input.source) {
3430
await core.group(`Download docker`, async () => {
3531
toolDir = await install.download();
3632
});

0 commit comments

Comments
 (0)