mirror of
https://github.com/docker/login-action.git
synced 2026-04-08 15:58:17 +01:00
Compare commits
5 Commits
20e0a61734
...
f95fe26bb1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f95fe26bb1 | ||
|
|
e9e40199d9 | ||
|
|
916386b000 | ||
|
|
5b3f94a294 | ||
|
|
f9cc43b63d |
@@ -50,7 +50,7 @@ test('logout calls exec', async () => {
|
||||
|
||||
const registry = 'https://ghcr.io';
|
||||
|
||||
await logout(registry);
|
||||
await logout(registry, '');
|
||||
|
||||
expect(execSpy).toHaveBeenCalledTimes(1);
|
||||
const callfunc = execSpy.mock.calls[0];
|
||||
|
||||
2
dist/index.js
generated
vendored
2
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,8 @@
|
||||
import path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as yaml from 'js-yaml';
|
||||
|
||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
|
||||
|
||||
export interface Inputs {
|
||||
registry: string;
|
||||
@@ -10,6 +14,15 @@ export interface Inputs {
|
||||
registryAuth: string;
|
||||
}
|
||||
|
||||
export interface Auth {
|
||||
registry: string;
|
||||
username: string;
|
||||
password: string;
|
||||
scope: string;
|
||||
ecr: string;
|
||||
configDir: string;
|
||||
}
|
||||
|
||||
export function getInputs(): Inputs {
|
||||
return {
|
||||
registry: core.getInput('registry'),
|
||||
@@ -21,3 +34,49 @@ export function getInputs(): Inputs {
|
||||
registryAuth: core.getInput('registry-auth')
|
||||
};
|
||||
}
|
||||
|
||||
export function getAuthList(inputs: Inputs): Array<Auth> {
|
||||
if (inputs.registryAuth && (inputs.registry || inputs.username || inputs.password || inputs.scope || inputs.ecr)) {
|
||||
throw new Error('Cannot use registry-auth with other inputs');
|
||||
}
|
||||
let auths: Array<Auth> = [];
|
||||
if (!inputs.registryAuth) {
|
||||
auths.push({
|
||||
registry: inputs.registry || 'docker.io',
|
||||
username: inputs.username,
|
||||
password: inputs.password,
|
||||
scope: inputs.scope,
|
||||
ecr: inputs.ecr || 'auto',
|
||||
configDir: scopeToConfigDir(inputs.registry, inputs.scope)
|
||||
});
|
||||
} else {
|
||||
auths = (yaml.load(inputs.registryAuth) as Array<Auth>).map(auth => {
|
||||
core.setSecret(auth.password); // redacted in workflow logs
|
||||
return {
|
||||
registry: auth.registry || 'docker.io',
|
||||
username: auth.username,
|
||||
password: auth.password,
|
||||
scope: auth.scope,
|
||||
ecr: auth.ecr || 'auto',
|
||||
configDir: scopeToConfigDir(auth.registry || 'docker.io', auth.scope)
|
||||
};
|
||||
});
|
||||
}
|
||||
if (auths.length == 0) {
|
||||
throw new Error('No registry to login');
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
|
||||
export function scopeToConfigDir(registry: string, scope?: string): string {
|
||||
if (!scope || scope === '') {
|
||||
return '';
|
||||
}
|
||||
let configDir = path.join(Buildx.configDir, 'config', registry === 'docker.io' ? 'registry-1.docker.io' : registry);
|
||||
if (scope.startsWith('@')) {
|
||||
configDir += scope;
|
||||
} else {
|
||||
configDir = path.join(configDir, scope);
|
||||
}
|
||||
return configDir;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import path from 'path';
|
||||
import * as aws from './aws';
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import * as aws from './aws';
|
||||
import * as context from './context';
|
||||
|
||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
|
||||
|
||||
export interface Auth {
|
||||
registry: string;
|
||||
username: string;
|
||||
password: string;
|
||||
scope?: string;
|
||||
ecr: string;
|
||||
}
|
||||
|
||||
export async function login(auth: Auth): Promise<void> {
|
||||
export async function login(auth: context.Auth): Promise<void> {
|
||||
if (/true/i.test(auth.ecr) || (auth.ecr == 'auto' && aws.isECR(auth.registry))) {
|
||||
await loginECR(auth.registry, auth.username, auth.password, auth.scope);
|
||||
} else {
|
||||
@@ -21,9 +13,19 @@ export async function login(auth: Auth): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function logout(registry: string): Promise<void> {
|
||||
export async function logout(registry: string, configDir: string): Promise<void> {
|
||||
let envs: {[key: string]: string} | undefined;
|
||||
if (configDir !== '') {
|
||||
envs = Object.assign({}, process.env, {
|
||||
DOCKER_CONFIG: configDir
|
||||
}) as {
|
||||
[key: string]: string;
|
||||
};
|
||||
core.info(`Alternative config dir: ${configDir}`);
|
||||
}
|
||||
await Docker.getExecOutput(['logout', registry], {
|
||||
ignoreReturnCode: true
|
||||
ignoreReturnCode: true,
|
||||
env: envs
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
core.warning(res.stderr.trim());
|
||||
@@ -54,19 +56,13 @@ export async function loginECR(registry: string, username: string, password: str
|
||||
|
||||
async function loginExec(registry: string, username: string, password: string, scope?: string): Promise<void> {
|
||||
let envs: {[key: string]: string} | undefined;
|
||||
if (scope && scope.length > 0) {
|
||||
let dockerConfigDir = path.join(Buildx.configDir, 'config', registry === 'docker.io' ? 'registry-1.docker.io' : registry);
|
||||
if (scope.startsWith('@')) {
|
||||
dockerConfigDir += scope;
|
||||
} else {
|
||||
dockerConfigDir = path.join(dockerConfigDir, scope);
|
||||
}
|
||||
if (scope && scope !== '') {
|
||||
envs = Object.assign({}, process.env, {
|
||||
DOCKER_CONFIG: dockerConfigDir
|
||||
DOCKER_CONFIG: context.scopeToConfigDir(registry, scope)
|
||||
}) as {
|
||||
[key: string]: string;
|
||||
};
|
||||
core.info(`Logging into ${registry} with scope ${scope}...`);
|
||||
core.info(`Logging into ${registry} (scope ${scope})...`);
|
||||
} else {
|
||||
core.info(`Logging into ${registry}...`);
|
||||
}
|
||||
|
||||
36
src/main.ts
36
src/main.ts
@@ -1,4 +1,3 @@
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as core from '@actions/core';
|
||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||
|
||||
@@ -10,35 +9,14 @@ export async function main(): Promise<void> {
|
||||
const inputs: context.Inputs = context.getInputs();
|
||||
stateHelper.setLogout(inputs.logout);
|
||||
|
||||
if (inputs.registryAuth && (inputs.registry || inputs.username || inputs.password || inputs.scope || inputs.ecr)) {
|
||||
throw new Error('Cannot use registry-auth with other inputs');
|
||||
}
|
||||
const auths = context.getAuthList(inputs);
|
||||
stateHelper.setRegistries(Array.from(new Map(auths.map(auth => [`${auth.registry}|${auth.configDir}`, {registry: auth.registry, configDir: auth.configDir} as stateHelper.RegistryState])).values()));
|
||||
|
||||
if (!inputs.registryAuth) {
|
||||
stateHelper.setRegistries([inputs.registry || 'docker.io']);
|
||||
await docker.login({
|
||||
registry: inputs.registry || 'docker.io',
|
||||
username: inputs.username,
|
||||
password: inputs.password,
|
||||
scope: inputs.scope,
|
||||
ecr: inputs.ecr || 'auto'
|
||||
});
|
||||
if (auths.length === 1) {
|
||||
await docker.login(auths[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
const auths = (yaml.load(inputs.registryAuth) as docker.Auth[]).map(auth => ({
|
||||
registry: auth.registry || 'docker.io',
|
||||
username: auth.username,
|
||||
password: auth.password,
|
||||
scope: auth.scope,
|
||||
ecr: auth.ecr || 'auto'
|
||||
}));
|
||||
if (auths.length == 0) {
|
||||
throw new Error('No registry to login');
|
||||
}
|
||||
|
||||
stateHelper.setRegistries(auths.map(auth => auth.registry).filter((value, index, self) => self.indexOf(value) === index));
|
||||
|
||||
for (const auth of auths) {
|
||||
await core.group(`Login to ${auth.registry}`, async () => {
|
||||
await docker.login(auth);
|
||||
@@ -50,8 +28,10 @@ async function post(): Promise<void> {
|
||||
if (!stateHelper.logout) {
|
||||
return;
|
||||
}
|
||||
for (const registry of stateHelper.registries.split(',')) {
|
||||
await docker.logout(registry);
|
||||
for (const registryState of stateHelper.registries) {
|
||||
await core.group(`Logout from ${registryState.registry}`, async () => {
|
||||
await docker.logout(registryState.registry, registryState.configDir);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
export const registries = process.env['STATE_registries'] || '';
|
||||
export const registries = process.env['STATE_registries'] ? (JSON.parse(process.env['STATE_registries']) as Array<RegistryState>) : [];
|
||||
export const logout = /true/i.test(process.env['STATE_logout'] || '');
|
||||
|
||||
export function setRegistries(registries: string[]) {
|
||||
core.saveState('registries', registries.join(','));
|
||||
export interface RegistryState {
|
||||
registry: string;
|
||||
configDir: string;
|
||||
}
|
||||
|
||||
export function setRegistries(registries: Array<RegistryState>) {
|
||||
core.saveState('registries', JSON.stringify(registries));
|
||||
}
|
||||
|
||||
export function setLogout(logout: boolean) {
|
||||
|
||||
Reference in New Issue
Block a user