mirror of
https://github.com/redhat-actions/push-to-registry.git
synced 2025-02-23 10:31:22 +01:00
Copy exec from oc-login for better error reporting
Signed-off-by: Tim Etchells <tetchell@redhat.com>
This commit is contained in:
parent
4f00df14d1
commit
7c3d1059c8
4 changed files with 41 additions and 44 deletions
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
68
src/index.ts
68
src/index.ts
|
@ -1,7 +1,7 @@
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import { CommandResult } from './types';
|
import * as path from "path";
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
let imageToPush = core.getInput('image', { required: true });
|
let imageToPush = core.getInput('image', { required: true });
|
||||||
|
@ -21,55 +21,63 @@ export async function run(): Promise<void> {
|
||||||
core.info(pushMsg);
|
core.info(pushMsg);
|
||||||
|
|
||||||
//check if images exist in podman's local storage
|
//check if images exist in podman's local storage
|
||||||
const checkImages: CommandResult = await execute(podman, ['images', '--format', 'json']);
|
const checkImages = await execute(podman, ['images', '--format', 'json']);
|
||||||
if (checkImages.succeeded === false) {
|
|
||||||
return Promise.reject(new Error(checkImages.reason));
|
const parsedCheckImages = JSON.parse(checkImages.stdout);
|
||||||
}
|
|
||||||
const parsedCheckImages = JSON.parse(checkImages.output);
|
|
||||||
// this is to temporarily solve an issue with the case-sensitive of the property field name. i.e it is Names or names??
|
// this is to temporarily solve an issue with the case-sensitive of the property field name. i.e it is Names or names??
|
||||||
const nameKeyMixedCase = parsedCheckImages[0] && Object.keys(parsedCheckImages[0]).find(key => 'names' === key.toLowerCase());
|
const nameKeyMixedCase = parsedCheckImages[0] && Object.keys(parsedCheckImages[0]).find(key => 'names' === key.toLowerCase());
|
||||||
const imagesFound = parsedCheckImages.
|
const imagesFound = parsedCheckImages.
|
||||||
filter(image => image[nameKeyMixedCase] && image[nameKeyMixedCase].find(name => name.includes(`${imageToPush}`))).
|
filter((image: string) => image[nameKeyMixedCase] && image[nameKeyMixedCase].find((name: string) => name.includes(`${imageToPush}`))).
|
||||||
map(image => image[nameKeyMixedCase]);
|
map((image: string ) => image[nameKeyMixedCase]);
|
||||||
|
|
||||||
if (imagesFound.length === 0) {
|
if (imagesFound.length === 0) {
|
||||||
//check inside the docker daemon local storage
|
//check inside the docker daemon local storage
|
||||||
const pullFromDocker: CommandResult = await execute(podman, ['pull', `docker-daemon:${imageToPush}`]);
|
await execute(podman, ['pull', `docker-daemon:${imageToPush}`]);
|
||||||
if (pullFromDocker.succeeded === false) {
|
|
||||||
return Promise.reject(new Error(`Unable to find the image to push`));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// push image
|
// push image
|
||||||
const registryPath = `${registry.replace(/\/$/, '')}/${imageToPush}`;
|
const registryPath = `${registry.replace(/\/$/, '')}/${imageToPush}`;
|
||||||
|
|
||||||
const creds: string = `${username}:${password}`;
|
const creds: string = `${username}:${password}`;
|
||||||
const push: CommandResult = await execute(podman, ['push', '--quiet', '--creds', creds, imageToPush, registryPath]);
|
|
||||||
if (push.succeeded === false) {
|
await execute(podman, ['push', '--quiet', '--creds', creds, imageToPush, registryPath]);
|
||||||
return Promise.reject(new Error(push.reason));
|
|
||||||
}
|
|
||||||
core.info(`Successfully pushed ${imageToPush} to ${registryPath}.`);
|
core.info(`Successfully pushed ${imageToPush} to ${registryPath}.`);
|
||||||
|
|
||||||
core.setOutput('registry-path', registryPath);
|
core.setOutput('registry-path', registryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function execute(executable: string, args: string[]): Promise<CommandResult> {
|
async function execute(executable: string, args: string[], execOptions: exec.ExecOptions = {}): Promise<{ exitCode: number, stdout: string, stderr: string }> {
|
||||||
let output = '';
|
let stdout = "";
|
||||||
let error = '';
|
let stderr = "";
|
||||||
|
|
||||||
const options: exec.ExecOptions = {};
|
const finalExecOptions = { ...execOptions };
|
||||||
options.listeners = {
|
finalExecOptions.ignoreReturnCode = true; // the return code is processed below
|
||||||
stdout: (data: Buffer): void => {
|
|
||||||
output += data.toString();
|
finalExecOptions.listeners = {
|
||||||
|
stdline: (line) => {
|
||||||
|
stdout += line + "\n";
|
||||||
|
},
|
||||||
|
errline: (line) => {
|
||||||
|
stderr += line + "\n"
|
||||||
},
|
},
|
||||||
stderr: (data: Buffer): void => {
|
|
||||||
error += data.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const exitCode = await exec.exec(executable, args, finalExecOptions);
|
||||||
|
|
||||||
|
if (execOptions.ignoreReturnCode !== true && exitCode !== 0) {
|
||||||
|
// Throwing the stderr as part of the Error makes the stderr show up in the action outline, which saves some clicking when debugging.
|
||||||
|
let error = `${path.basename(executable)} exited with code ${exitCode}`;
|
||||||
|
if (stderr) {
|
||||||
|
error += `\n${stderr}`;
|
||||||
|
}
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
exitCode, stdout, stderr
|
||||||
};
|
};
|
||||||
const exitCode = await exec.exec(executable, args, options);
|
|
||||||
if (exitCode === 1) {
|
|
||||||
return Promise.resolve({ succeeded: false, error });
|
|
||||||
}
|
|
||||||
return Promise.resolve({ succeeded: true, output });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run().catch(core.setFailed);
|
run().catch(core.setFailed);
|
||||||
|
|
11
src/types.ts
11
src/types.ts
|
@ -1,11 +0,0 @@
|
||||||
export interface CommandSucceeeded {
|
|
||||||
readonly succeeded: true;
|
|
||||||
readonly output?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CommandFailed {
|
|
||||||
readonly succeeded: false;
|
|
||||||
readonly reason?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CommandResult = CommandFailed | CommandSucceeeded;
|
|
Loading…
Add table
Reference in a new issue