Skip to content

Commit 6dce2eb

Browse files
committed
add opt-in skip for missing login credentials
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 3227f53 commit 6dce2eb

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

__tests__/docker.test.ts

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {expect, jest, test} from '@jest/globals';
1+
import {afterEach, beforeEach, expect, jest, test} from '@jest/globals';
22
import * as path from 'path';
33

44
import {loginStandard, logout} from '../src/docker';
@@ -7,6 +7,14 @@ import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
77

88
process.env['RUNNER_TEMP'] = path.join(__dirname, 'runner');
99

10+
beforeEach(() => {
11+
delete process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS;
12+
});
13+
14+
afterEach(() => {
15+
delete process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS;
16+
});
17+
1018
test('loginStandard calls exec', async () => {
1119
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1220
// @ts-ignore
@@ -20,7 +28,7 @@ test('loginStandard calls exec', async () => {
2028

2129
const username = 'dbowie';
2230
const password = 'groundcontrol';
23-
const registry = 'https://ghcr.io';
31+
const registry = 'ghcr.io';
2432

2533
await loginStandard(registry, username, password);
2634

@@ -37,6 +45,60 @@ test('loginStandard calls exec', async () => {
3745
});
3846
});
3947

48+
test('loginStandard throws if username and password are missing', async () => {
49+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
50+
// @ts-ignore
51+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
52+
await expect(loginStandard('ghcr.io', '', '')).rejects.toThrow('Username and password required');
53+
expect(execSpy).not.toHaveBeenCalled();
54+
});
55+
56+
test('loginStandard throws if username is missing', async () => {
57+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
58+
// @ts-ignore
59+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
60+
await expect(loginStandard('ghcr.io', '', 'groundcontrol')).rejects.toThrow('Username required');
61+
expect(execSpy).not.toHaveBeenCalled();
62+
});
63+
64+
test('loginStandard throws if password is missing', async () => {
65+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
66+
// @ts-ignore
67+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
68+
await expect(loginStandard('ghcr.io', 'dbowie', '')).rejects.toThrow('Password required');
69+
expect(execSpy).not.toHaveBeenCalled();
70+
});
71+
72+
test('loginStandard skips if both credentials are missing and env opt-in is enabled', async () => {
73+
process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS = 'true';
74+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
75+
// @ts-ignore
76+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
77+
78+
await expect(loginStandard('ghcr.io', '', '')).resolves.toBeUndefined();
79+
expect(execSpy).not.toHaveBeenCalled();
80+
});
81+
82+
test('loginStandard skips if username is missing and env opt-in is enabled', async () => {
83+
process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS = 'true';
84+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
85+
// @ts-ignore
86+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
87+
88+
await expect(loginStandard('ghcr.io', '', 'groundcontrol')).resolves.toBeUndefined();
89+
expect(execSpy).not.toHaveBeenCalled();
90+
});
91+
92+
test('loginStandard skips if password is missing and env opt-in is enabled', async () => {
93+
process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS = 'true';
94+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
95+
// @ts-ignore
96+
const execSpy = jest.spyOn(Docker, 'getExecOutput');
97+
98+
await expect(loginStandard('ghcr.io', 'dbowie', '')).resolves.toBeUndefined();
99+
expect(execSpy).not.toHaveBeenCalled();
100+
});
101+
40102
test('logout calls exec', async () => {
41103
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
42104
// @ts-ignore
@@ -48,7 +110,7 @@ test('logout calls exec', async () => {
48110
};
49111
});
50112

51-
const registry = 'https://ghcr.io';
113+
const registry = 'ghcr.io';
52114

53115
await logout(registry, '');
54116

src/docker.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as aws from './aws';
44
import * as context from './context';
55

66
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
7+
import {Util} from '@docker/actions-toolkit/lib/util';
78

89
export async function login(auth: context.Auth): Promise<void> {
910
if (/true/i.test(auth.ecr) || (auth.ecr == 'auto' && aws.isECR(auth.registry))) {
@@ -34,6 +35,10 @@ export async function logout(registry: string, configDir: string): Promise<void>
3435
}
3536

3637
export async function loginStandard(registry: string, username: string, password: string, scope?: string): Promise<void> {
38+
if ((!username || !password) && skipLoginIfMissingCredsEnabled()) {
39+
core.info(`Skipping login to ${registry}. Username or password is not set and DOCKER_LOGIN_SKIP_IF_MISSING_CREDS is enabled.`);
40+
return;
41+
}
3742
if (!username && !password) {
3843
throw new Error('Username and password required');
3944
}
@@ -79,3 +84,10 @@ async function loginExec(registry: string, username: string, password: string, s
7984
core.info('Login Succeeded!');
8085
});
8186
}
87+
88+
function skipLoginIfMissingCredsEnabled(): boolean {
89+
if (process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS) {
90+
return Util.parseBool(process.env.DOCKER_LOGIN_SKIP_IF_MISSING_CREDS);
91+
}
92+
return false;
93+
}

0 commit comments

Comments
 (0)