Skip to content

Commit 585870b

Browse files
Merge pull request #83 from step-security/auto-cherry-pick
chore: Cherry-picked changes from upstream
2 parents 588c9bd + 00094a8 commit 585870b

File tree

8 files changed

+237
-21
lines changed

8 files changed

+237
-21
lines changed

.github/dependabot.yml

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ updates:
44
directory: "/"
55
schedule:
66
interval: "daily"
7+
ignore:
8+
# ignore this dependency
9+
# it seems a bug with dependabot as pining to commit sha should not
10+
# trigger a new version similar to https://github.com/docker/buildx/pull/2222#issuecomment-1919092153
11+
- dependency-name: "docker/actions-toolkit"
712
labels:
813
- "dependencies"
914
- "bot"

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ The following inputs can be used as `step.with` keys
111111
| `daemon-config` | String | | [Docker daemon JSON configuration](https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file) |
112112
| `context` | String | `setup-docker-action` | Docker context name. |
113113
| `set-host` | Bool | `false` | Set `DOCKER_HOST` environment variable to docker socket path. |
114+
| `rootless` | Bool | `false` | Start daemon in rootless mode |
114115

115116
### outputs
116117

__tests__/context.test.ts

+134-7
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ describe('getInputs', () => {
1919
new Map<string, string>([
2020
['version', 'v24.0.8'],
2121
['set-host', 'false'],
22+
['rootless', 'false'],
2223
]),
2324
{
24-
version: 'v24.0.8',
25-
channel: '',
25+
source: {
26+
type: 'archive',
27+
version: 'v24.0.8',
28+
channel: 'stable'
29+
},
2630
context: '',
2731
daemonConfig: '',
32+
rootless: false,
2833
setHost: false
2934
} as context.Inputs
3035
],
@@ -36,28 +41,150 @@ describe('getInputs', () => {
3641
['context', 'foo'],
3742
['daemon-config', `{"debug":true,"features":{"containerd-snapshotter":true}}`],
3843
['set-host', 'false'],
44+
['rootless', 'false'],
3945
]),
4046
{
41-
version: 'v24.0.0-rc.4',
42-
channel: 'test',
47+
source: {
48+
type: 'archive',
49+
version: 'v24.0.0-rc.4',
50+
channel: 'test'
51+
},
4352
context: 'foo',
4453
daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`,
54+
rootless: false,
4555
setHost: false
4656
} as context.Inputs
4757
],
4858
[
4959
2,
5060
new Map<string, string>([
5161
['set-host', 'true'],
62+
['rootless', 'false'],
5263
]),
5364
{
54-
version: 'latest',
55-
channel: '',
65+
source: {
66+
type: 'archive',
67+
version: 'latest',
68+
channel: 'stable',
69+
},
5670
context: '',
5771
daemonConfig: '',
72+
rootless: false,
5873
setHost: true
5974
} as context.Inputs
60-
]
75+
],
76+
[
77+
3,
78+
new Map<string, string>([
79+
['version', 'type=image,tag=master'],
80+
['context', 'foo'],
81+
['daemon-config', `{"debug":true,"features":{"containerd-snapshotter":true}}`],
82+
['set-host', 'false'],
83+
['rootless', 'false'],
84+
]),
85+
{
86+
source: {
87+
type: 'image',
88+
tag: 'master',
89+
},
90+
context: 'foo',
91+
daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`,
92+
rootless: false,
93+
setHost: false
94+
} as context.Inputs
95+
],
96+
[
97+
4,
98+
new Map<string, string>([
99+
['version', 'type=image'],
100+
['set-host', 'false'],
101+
['rootless', 'false'],
102+
]),
103+
{
104+
source: {
105+
type: 'image',
106+
tag: 'latest',
107+
},
108+
context: '',
109+
daemonConfig: '',
110+
rootless: false,
111+
setHost: false
112+
} as context.Inputs
113+
],
114+
[
115+
5,
116+
new Map<string, string>([
117+
['version', 'type=archive'],
118+
['set-host', 'false'],
119+
['rootless', 'false'],
120+
]),
121+
{
122+
source: {
123+
type: 'archive',
124+
version: 'latest',
125+
channel: 'stable',
126+
},
127+
setHost: false,
128+
context: '',
129+
daemonConfig: '',
130+
rootless: false,
131+
} as context.Inputs
132+
],
133+
[
134+
6,
135+
new Map<string, string>([
136+
['version', 'version=v27.2.0,channel=test'],
137+
['set-host', 'false'],
138+
['rootless', 'false'],
139+
]),
140+
{
141+
source: {
142+
type: 'archive',
143+
version: 'v27.2.0',
144+
channel: 'test',
145+
},
146+
setHost: false,
147+
context: '',
148+
daemonConfig: '',
149+
rootless: false,
150+
} as context.Inputs
151+
],
152+
[
153+
7,
154+
new Map<string, string>([
155+
['version', 'type=image,tag=27.2.1'],
156+
['set-host', 'false'],
157+
['rootless', 'false'],
158+
]),
159+
{
160+
source: {
161+
type: 'image',
162+
tag: '27.2.1',
163+
},
164+
setHost: false,
165+
context: '',
166+
daemonConfig: '',
167+
rootless: false,
168+
} as context.Inputs
169+
],
170+
[
171+
8,
172+
new Map<string, string>([
173+
['version', 'type=image,tag=27.2.1'],
174+
['set-host', 'false'],
175+
['rootless', 'true']
176+
]),
177+
{
178+
source: {
179+
type: 'image',
180+
tag: '27.2.1',
181+
},
182+
setHost: false,
183+
context: '',
184+
daemonConfig: '',
185+
rootless: true,
186+
} as context.Inputs
187+
],
61188
])(
62189
'[%d] given %p as inputs, returns %p',
63190
async (num: number, inputs: Map<string, string>, expected: context.Inputs) => {

action.yml

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ inputs:
2323
description: 'Set DOCKER_HOST environment variable to docker socket path'
2424
default: 'false'
2525
required: false
26+
rootless:
27+
description: 'Enable Docker rootless mode'
28+
default: 'false'
29+
required: false
2630

2731
outputs:
2832
sock:

dist/index.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/context.ts

+84-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,98 @@
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;
10+
rootless: boolean;
911
}
1012

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

src/main.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import * as crypto from 'crypto';
12
import os from 'os';
23
import path from 'path';
3-
import * as uuid from 'uuid';
44
import * as core from '@actions/core';
55
import * as actionsToolkit from '@docker/actions-toolkit';
66
import {Install} from '@docker/actions-toolkit/lib/docker/install';
@@ -31,21 +31,21 @@ actionsToolkit.run(
3131
await validateSubscription();
3232

3333
const input: context.Inputs = context.getInputs();
34-
const runDir = path.join(os.homedir(), `setup-docker-action-${uuid.v4().slice(0, 8)}`);
34+
const runDir = path.join(os.homedir(), `setup-docker-action-${crypto.randomUUID().slice(0, 8)}`);
3535

3636
if (input.context == 'default') {
3737
throw new Error(`'default' context cannot be used.`);
3838
}
3939

4040
const install = new Install({
4141
runDir: runDir,
42-
version: input.version,
43-
channel: input.channel || 'stable',
42+
source: input.source,
43+
rootless: input.rootless,
4444
contextName: input.context || 'setup-docker-action',
4545
daemonConfig: input.daemonConfig
4646
});
4747
let toolDir;
48-
if (!(await Docker.isAvailable()) || input.version) {
48+
if (!(await Docker.isAvailable()) || input.source) {
4949
await core.group(`Download docker`, async () => {
5050
toolDir = await install.download();
5151
});

0 commit comments

Comments
 (0)