2020-11-07 13:04:04 +01:00
|
|
|
import * as core from '@actions/core';
|
|
|
|
import * as exec from '@actions/exec';
|
|
|
|
import * as io from '@actions/io';
|
|
|
|
import { CommandResult } from './types';
|
|
|
|
|
|
|
|
export async function run(): Promise<void> {
|
2020-11-16 14:06:29 +01:00
|
|
|
let imageToPush = core.getInput('image-to-push');
|
2020-11-13 15:12:47 +01:00
|
|
|
const tag = core.getInput('tag') || 'latest';
|
|
|
|
const registry = core.getInput('registry');
|
2020-11-07 13:04:04 +01:00
|
|
|
const username = core.getInput('username');
|
2020-11-13 15:12:47 +01:00
|
|
|
const password = core.getInput('password');
|
2020-11-07 13:04:04 +01:00
|
|
|
|
|
|
|
// get podman cli
|
2020-11-13 15:12:47 +01:00
|
|
|
const podman = await io.which('podman', true);
|
|
|
|
|
2020-11-16 14:06:29 +01:00
|
|
|
imageToPush = `${imageToPush}:${tag}`;
|
2020-11-13 15:12:47 +01:00
|
|
|
//check if images exist in podman's local storage
|
|
|
|
const checkImages: CommandResult = await execute(podman, ['images', '--format', 'json']);
|
|
|
|
if (checkImages.succeeded === false) {
|
|
|
|
return Promise.reject(new Error(checkImages.reason));
|
|
|
|
}
|
|
|
|
const parsedCheckImages = JSON.parse(checkImages.output);
|
2020-11-13 15:37:29 +01:00
|
|
|
// 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());
|
2020-11-13 15:12:47 +01:00
|
|
|
const imagesFound = parsedCheckImages.
|
2020-11-16 14:06:29 +01:00
|
|
|
filter(image => image[nameKeyMixedCase] && image[nameKeyMixedCase].find(name => name.includes(`${imageToPush}`))).
|
2020-11-13 15:37:29 +01:00
|
|
|
map(image => image[nameKeyMixedCase]);
|
2020-11-13 15:12:47 +01:00
|
|
|
if (imagesFound.length === 0) {
|
|
|
|
//check inside the docker daemon local storage
|
2020-11-16 14:06:29 +01:00
|
|
|
const pullFromDocker: CommandResult = await execute(podman, ['pull', `docker-daemon:${imageToPush}`]);
|
2020-11-13 15:12:47 +01:00
|
|
|
if (pullFromDocker.succeeded === false) {
|
|
|
|
return Promise.reject(new Error(`Unable to find the image to push`));
|
|
|
|
}
|
|
|
|
}
|
2020-11-07 13:04:04 +01:00
|
|
|
|
|
|
|
// push image
|
2020-11-16 14:06:29 +01:00
|
|
|
const registryUrl = `${registry.replace(/\/$/, '')}/${imageToPush}`;
|
2020-11-13 15:12:47 +01:00
|
|
|
const push: CommandResult = await execute(podman, ['push', '--creds', `${username}:${password}`, `${imageToPush}`, `${registryUrl}`]);
|
2020-11-07 13:04:04 +01:00
|
|
|
if (push.succeeded === false) {
|
|
|
|
return Promise.reject(new Error(push.reason));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function execute(executable: string, args: string[]): Promise<CommandResult> {
|
2020-11-13 15:12:47 +01:00
|
|
|
let output = '';
|
2020-11-07 13:04:04 +01:00
|
|
|
let error = '';
|
|
|
|
|
|
|
|
const options: exec.ExecOptions = {};
|
|
|
|
options.listeners = {
|
2020-11-13 15:12:47 +01:00
|
|
|
stdout: (data: Buffer): void => {
|
|
|
|
output += data.toString();
|
|
|
|
},
|
2020-11-07 13:04:04 +01:00
|
|
|
stderr: (data: Buffer): void => {
|
|
|
|
error += data.toString();
|
|
|
|
}
|
|
|
|
};
|
2020-11-07 13:33:57 +01:00
|
|
|
const exitCode = await exec.exec(executable, args, options);
|
2020-11-07 13:04:04 +01:00
|
|
|
if (exitCode === 1) {
|
2020-11-13 15:12:47 +01:00
|
|
|
return Promise.resolve({ succeeded: false, error });
|
2020-11-07 13:04:04 +01:00
|
|
|
}
|
2020-11-13 15:12:47 +01:00
|
|
|
return Promise.resolve({ succeeded: true, output });
|
2020-11-07 13:04:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
run().catch(core.setFailed);
|