Skip to content

Commit

Permalink
testing custom action
Browse files Browse the repository at this point in the history
  • Loading branch information
Uroš Marolt committed Jan 9, 2024
1 parent ca768fb commit 540e984
Show file tree
Hide file tree
Showing 7 changed files with 1,492 additions and 23 deletions.
1,392 changes: 1,379 additions & 13 deletions .github/actions/node/builder/index.js

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions .github/actions/node/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import { loadInputs } from './inputs'
import { buildStep } from './steps'
import { getInputs } from './inputs'
import { IS_POST } from './state'
import * as core from '@actions/core'
import { loadBuilderDefinitions } from './utils'
import { ActionStep } from './types'
/**
* Runs the action
*/
async function run() {
const inputs = await loadInputs()

const builderDefinitions = await loadBuilderDefinitions()
for (const def of builderDefinitions) {
core.info(`Loaded builder definition: ${JSON.stringify(def)}`)
}
const inputs = await getInputs()

for (const step of inputs.steps) {
core.info(`Running step: ${step}`)
switch (step) {
case ActionStep.BUILD: {
await buildStep()
break
}

default:
core.error(`Unknown action step: ${step}!`)
throw new Error(`Unknown action step: ${step}!`)
}
}
}

Expand Down
30 changes: 29 additions & 1 deletion .github/actions/node/src/inputs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ActionStep, IActionInputs, IBuildInput, IDeployInput, IPushInput } from './types'
import * as core from '@actions/core'
import { getBuilderDefinitions } from './utils'

const getBuildInputs = (): IBuildInput => {
const tag = core.getInput('tag')

return {
tag,
images: [],
}
}

Expand Down Expand Up @@ -44,7 +46,12 @@ const getDeployIUputs = (): IDeployInput => {
}
}

export const loadInputs = async (): Promise<IActionInputs> => {
let inputs: IActionInputs | undefined
export const getInputs = async (): Promise<IActionInputs> => {
if (inputs !== undefined) {
return inputs
}

const actionSteps = getInputList('steps') as ActionStep[]

if (actionSteps.length === 0) {
Expand Down Expand Up @@ -74,6 +81,27 @@ export const loadInputs = async (): Promise<IActionInputs> => {
}
}

if (results[ActionStep.BUILD] !== undefined) {
if (results[ActionStep.BUILD].images.length === 0 && results[ActionStep.DEPLOY] !== undefined) {
// calculate images from services
const buildDefinitions = await getBuilderDefinitions()

const images: string[] = []
for (const service of results[ActionStep.DEPLOY].services) {
const definition = buildDefinitions.find((d) => d.services.includes(service))
if (definition === undefined) {
core.error(`No builder definition found for service: ${service}!`)
throw new Error(`No builder definition found for service: ${service}!`)
}

if (!images.includes(definition.imageName)) {
images.push(definition.imageName)
}
}
}
}

inputs = results
return results
}

Expand Down
8 changes: 8 additions & 0 deletions .github/actions/node/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ export const IS_POST = !!process.env['STATE_isPost']
if (!IS_POST) {
core.saveState('isPost', 'true')
}

export const setImageTag = (image: string, tag: string): void => {
core.saveState(`imageTag.${image}`, tag)
}

export const getImageTag = (image: string): string | undefined => {
return core.getState(`imageTag.${image}`)
}
50 changes: 50 additions & 0 deletions .github/actions/node/src/steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { getInputs } from './inputs'
import { setImageTag } from './state'
import { ActionStep } from './types'
import * as core from '@actions/core'
import * as exec from '@actions/exec'

export const buildStep = async (): Promise<void> => {
const inputs = await getInputs()

if (inputs[ActionStep.BUILD] === undefined) {
core.error('No build inputs provided!')
throw new Error('No build inputs provided!')
}

const { images, tag } = inputs[ActionStep.BUILD]
if (images.length === 0) {
core.error('No images provided!')
throw new Error('No images provided!')
}

if (!tag) {
core.error('No tag provided!')
throw new Error('No tag provided!')
}

const timestamp = Math.floor(Date.now() / 1000)

const actualTag = `${tag}.${timestamp}`

for (const image of images) {
core.info(`Building image: ${image}:${actualTag}`)
const exitCode = await exec.exec('bash', ['./scripts/cli', 'build', image, tag], {
listeners: {
stdout: (data) => {
core.info(`${image} builder: ${data.toString()}`)
},
stderr: (data) => {
core.error(`${image} builder error: ${data.toString()}`)
},
},
})

if (exitCode !== 0) {
core.error(`Failed to build image: ${image}:${actualTag}`)
throw new Error(`Failed to build image: ${image}:${actualTag}`)
}

setImageTag(image, actualTag)
}
}
3 changes: 3 additions & 0 deletions .github/actions/node/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export enum ActionStep {
export interface IBuildInput {
// image version tag
tag: string

// images to build
images: string[]
}

export interface IPushInput {
Expand Down
10 changes: 9 additions & 1 deletion .github/actions/node/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import dotenv from 'dotenv'
import { IBuilderDefinition } from './types'
import fs from 'fs'

export const loadBuilderDefinitions = async (): Promise<IBuilderDefinition[]> => {
let definitions: IBuilderDefinition[] | undefined

export const getBuilderDefinitions = async (): Promise<IBuilderDefinition[]> => {
if (definitions !== undefined) {
return definitions
}

const results: IBuilderDefinition[] = []
const files = fs.readdirSync('./scripts/builders')

Expand Down Expand Up @@ -36,5 +42,7 @@ export const loadBuilderDefinitions = async (): Promise<IBuilderDefinition[]> =>
}
}

definitions = results

return results
}

0 comments on commit 540e984

Please sign in to comment.