From 4c6545aa74710a476f8ef88e5ddc95521dc725d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uro=C5=A1=20Marolt?= Date: Tue, 9 Jan 2024 13:25:40 +0100 Subject: [PATCH] testing custom action --- .github/actions/node/builder/index.js | 96 +++++++++++++++++++++++---- .github/actions/node/src/index.ts | 12 +++- .github/actions/node/src/inputs.ts | 14 ++-- .github/actions/node/src/steps.ts | 85 +++++++++++++++++++++--- scripts/cli | 12 +++- 5 files changed, 187 insertions(+), 32 deletions(-) diff --git a/.github/actions/node/builder/index.js b/.github/actions/node/builder/index.js index 7f3552ff5a..423941baa0 100644 --- a/.github/actions/node/builder/index.js +++ b/.github/actions/node/builder/index.js @@ -26100,6 +26100,14 @@ async function run() { await (0, steps_1.buildStep)(); break; } + case types_1.ActionStep.PUSH: { + await (0, steps_1.pushStep)(); + break; + } + case types_1.ActionStep.DEPLOY: { + await (0, steps_1.deployStep)(); + break; + } default: core.error(`Unknown action step: ${step}!`); throw new Error(`Unknown action step: ${step}!`); @@ -26213,9 +26221,6 @@ const getInputs = async () => { throw new Error(`Unknown action step: ${step}!`); } } - // core.info(`Detected action steps: ${actionSteps.join(', ')}`) - // core.info(`Action inputs: ${JSON.stringify(results)}`) - // core.info(`Builder definitions: ${JSON.stringify(await getBuilderDefinitions())}`) if (results[types_1.ActionStep.BUILD] !== undefined) { if (results[types_1.ActionStep.BUILD].images.length === 0 && results[types_1.ActionStep.DEPLOY] !== undefined) { // calculate images from services @@ -26234,6 +26239,14 @@ const getInputs = async () => { results[types_1.ActionStep.BUILD].images = images; } } + if (results[types_1.ActionStep.PUSH] !== undefined && results[types_1.ActionStep.BUILD] === undefined) { + core.error('Push step provided without build step!'); + throw new Error('Push step provided without build step!'); + } + if (results[types_1.ActionStep.DEPLOY] !== undefined && results[types_1.ActionStep.PUSH] === undefined) { + core.error('Deploy step provided without push step!'); + throw new Error('Deploy step provided without push step!'); + } inputs = results; return results; }; @@ -26325,12 +26338,13 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.buildStep = void 0; +exports.deployStep = exports.pushStep = exports.buildStep = void 0; const inputs_1 = __nccwpck_require__(2117); const state_1 = __nccwpck_require__(5034); const types_1 = __nccwpck_require__(2106); const core = __importStar(__nccwpck_require__(3949)); const exec = __importStar(__nccwpck_require__(7912)); +const FAILED_IMAGE_TAG = 'FAILED_BUILD'; const buildStep = async () => { const inputs = await (0, inputs_1.getInputs)(); if (inputs[types_1.ActionStep.BUILD] === undefined) { @@ -26348,27 +26362,81 @@ const buildStep = async () => { } const timestamp = Math.floor(Date.now() / 1000); const actualTag = `${tag}.${timestamp}`; + const alreadyBuilt = []; for (const image of images) { + if (alreadyBuilt.includes(image)) { + core.info(`Skipping already built image: ${image}:${actualTag}`); + continue; + } core.info(`Building image: ${image}:${actualTag}`); const exitCode = await exec.exec('bash', ['cli', 'build', image, tag], { - listeners: { - stdout: (data) => { - core.info(data.toString()); - }, - stderr: (data) => { - core.info(data.toString()); - }, - }, cwd: './scripts', }); if (exitCode !== 0) { core.error(`Failed to build image: ${image}:${actualTag}`); - throw new Error(`Failed to build image: ${image}:${actualTag}`); + (0, state_1.setImageTag)(image, FAILED_IMAGE_TAG); + } + else { + alreadyBuilt.push(image); + (0, state_1.setImageTag)(image, actualTag); } - (0, state_1.setImageTag)(image, actualTag); } }; exports.buildStep = buildStep; +const pushStep = async () => { + var _a, _b; + const inputs = await (0, inputs_1.getInputs)(); + const images = (_b = (_a = inputs[types_1.ActionStep.BUILD]) === null || _a === void 0 ? void 0 : _a.images) !== null && _b !== void 0 ? _b : []; + const pushInput = inputs[types_1.ActionStep.PUSH]; + if (!pushInput) { + core.error('No push inputs provided!'); + throw new Error('No push inputs provided!'); + } + if (images.length === 0) { + core.error('No images provided!'); + throw new Error('No images provided!'); + } + // do a docker login + const exitCode = await exec.exec('docker', [ + 'login', + '--username', + pushInput.dockerUsername, + '--password', + pushInput.dockerPassword, + ]); + if (exitCode !== 0) { + core.error('Failed to login to docker!'); + throw new Error('Failed to login to docker!'); + } + // now push the images + const alreadyPushed = []; + for (const image of images) { + if (alreadyPushed.includes(image)) { + core.info(`Skipping already pushed image: ${image}`); + continue; + } + const tag = (0, state_1.getImageTag)(image); + if (tag == FAILED_IMAGE_TAG) { + core.info(`Skipping failed image: ${image}`); + continue; + } + core.info(`Pushing image: ${image}:${tag}!`); + const exitCode = await exec.exec('bash', ['cli', 'push', image, tag], { + cwd: './scripts', + }); + if (exitCode !== 0) { + core.error(`Failed to push image: ${image}:${tag}`); + (0, state_1.setImageTag)(image, FAILED_IMAGE_TAG); + } + else { + alreadyPushed.push(image); + (0, state_1.setImageTag)(image, tag); + } + } +}; +exports.pushStep = pushStep; +const deployStep = async () => { }; +exports.deployStep = deployStep; /***/ }), diff --git a/.github/actions/node/src/index.ts b/.github/actions/node/src/index.ts index 966ce5d206..c7b84b5ccd 100644 --- a/.github/actions/node/src/index.ts +++ b/.github/actions/node/src/index.ts @@ -1,4 +1,4 @@ -import { buildStep } from './steps' +import { buildStep, deployStep, pushStep } from './steps' import { getInputs } from './inputs' import { IS_POST } from './state' import * as core from '@actions/core' @@ -17,6 +17,16 @@ async function run() { break } + case ActionStep.PUSH: { + await pushStep() + break + } + + case ActionStep.DEPLOY: { + await deployStep() + break + } + default: core.error(`Unknown action step: ${step}!`) throw new Error(`Unknown action step: ${step}!`) diff --git a/.github/actions/node/src/inputs.ts b/.github/actions/node/src/inputs.ts index f5f504e126..529dca0c77 100644 --- a/.github/actions/node/src/inputs.ts +++ b/.github/actions/node/src/inputs.ts @@ -81,10 +81,6 @@ export const getInputs = async (): Promise => { } } - // core.info(`Detected action steps: ${actionSteps.join(', ')}`) - // core.info(`Action inputs: ${JSON.stringify(results)}`) - // core.info(`Builder definitions: ${JSON.stringify(await getBuilderDefinitions())}`) - if (results[ActionStep.BUILD] !== undefined) { if (results[ActionStep.BUILD].images.length === 0 && results[ActionStep.DEPLOY] !== undefined) { // calculate images from services @@ -107,6 +103,16 @@ export const getInputs = async (): Promise => { } } + if (results[ActionStep.PUSH] !== undefined && results[ActionStep.BUILD] === undefined) { + core.error('Push step provided without build step!') + throw new Error('Push step provided without build step!') + } + + if (results[ActionStep.DEPLOY] !== undefined && results[ActionStep.PUSH] === undefined) { + core.error('Deploy step provided without push step!') + throw new Error('Deploy step provided without push step!') + } + inputs = results return results } diff --git a/.github/actions/node/src/steps.ts b/.github/actions/node/src/steps.ts index 1032da5b1e..af9ce6e564 100644 --- a/.github/actions/node/src/steps.ts +++ b/.github/actions/node/src/steps.ts @@ -1,9 +1,11 @@ import { getInputs } from './inputs' -import { setImageTag } from './state' +import { getImageTag, setImageTag } from './state' import { ActionStep } from './types' import * as core from '@actions/core' import * as exec from '@actions/exec' +const FAILED_IMAGE_TAG = 'FAILED_BUILD' + export const buildStep = async (): Promise => { const inputs = await getInputs() @@ -27,25 +29,86 @@ export const buildStep = async (): Promise => { const actualTag = `${tag}.${timestamp}` + const alreadyBuilt: string[] = [] + for (const image of images) { + if (alreadyBuilt.includes(image)) { + core.info(`Skipping already built image: ${image}:${actualTag}`) + continue + } + core.info(`Building image: ${image}:${actualTag}`) const exitCode = await exec.exec('bash', ['cli', 'build', image, tag], { - listeners: { - stdout: (data) => { - core.info(data.toString()) - }, - stderr: (data) => { - core.info(data.toString()) - }, - }, cwd: './scripts', }) if (exitCode !== 0) { core.error(`Failed to build image: ${image}:${actualTag}`) - throw new Error(`Failed to build image: ${image}:${actualTag}`) + setImageTag(image, FAILED_IMAGE_TAG) + } else { + alreadyBuilt.push(image) + setImageTag(image, actualTag) + } + } +} + +export const pushStep = async (): Promise => { + const inputs = await getInputs() + const images = inputs[ActionStep.BUILD]?.images ?? [] + const pushInput = inputs[ActionStep.PUSH] + if (!pushInput) { + core.error('No push inputs provided!') + throw new Error('No push inputs provided!') + } + + if (images.length === 0) { + core.error('No images provided!') + throw new Error('No images provided!') + } + + // do a docker login + const exitCode = await exec.exec('docker', [ + 'login', + '--username', + pushInput.dockerUsername, + '--password', + pushInput.dockerPassword, + ]) + + if (exitCode !== 0) { + core.error('Failed to login to docker!') + throw new Error('Failed to login to docker!') + } + + // now push the images + const alreadyPushed: string[] = [] + for (const image of images) { + if (alreadyPushed.includes(image)) { + core.info(`Skipping already pushed image: ${image}`) + continue + } + + const tag = getImageTag(image) + + if (tag == FAILED_IMAGE_TAG) { + core.info(`Skipping failed image: ${image}`) + continue } - setImageTag(image, actualTag) + core.info(`Pushing image: ${image}:${tag}!`) + + const exitCode = await exec.exec('bash', ['cli', 'push', image, tag], { + cwd: './scripts', + }) + + if (exitCode !== 0) { + core.error(`Failed to push image: ${image}:${tag}`) + setImageTag(image, FAILED_IMAGE_TAG) + } else { + alreadyPushed.push(image) + setImageTag(image, tag) + } } } + +export const deployStep = async (): Promise => {} diff --git a/scripts/cli b/scripts/cli index 315d33bb4b..907a2514b0 100755 --- a/scripts/cli +++ b/scripts/cli @@ -107,8 +107,10 @@ function build_and_publish() { source $CLI_HOME/builders/$1.env - say "Building $REPO version $VERSION with dockerfile '$DOCKERFILE' and context '$CONTEXT' and pushing it to $REPO:$VERSION" - docker build --platform linux/amd64 --tag "$REPO:$VERSION" -f "$DOCKERFILE" "$CONTEXT" + if [[ ${BUILD} ]]; then + say "Building $REPO version $VERSION with dockerfile '$DOCKERFILE' and context '$CONTEXT' and pushing it to $REPO:$VERSION" + docker build --platform linux/amd64 --tag "$REPO:$VERSION" -f "$DOCKERFILE" "$CONTEXT" + fi if [[ ${PUSH} ]]; then say "Pushing image $REPO version $VERSION to $REPO:$VERSION" @@ -593,14 +595,20 @@ do exit; ;; build) + BUILD=1 build $2 $3 exit; ;; build-and-push) + BUILD=1 PUSH=1 build $2 $3 exit; ;; + push) + PUSH=1 + build $2 $3 + exit; db-backup) db_backup $2 exit;