Files
runner-container-hooks/packages/k8s/tests/test-setup.ts
T

166 lines
4.5 KiB
TypeScript
Raw Normal View History

import * as k8s from '@kubernetes/client-node'
2022-06-02 15:53:11 -04:00
import * as fs from 'fs'
import { HookData } from 'hooklib/lib'
import * as path from 'path'
2022-06-02 15:53:11 -04:00
import { v4 as uuidv4 } from 'uuid'
2022-06-06 00:21:44 -04:00
const kc = new k8s.KubeConfig()
kc.loadFromDefault()
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
export class TestHelper {
2022-06-02 15:53:11 -04:00
private tempDirPath: string
2022-06-06 00:21:44 -04:00
private podName: string
private runnerWorkdir: string
private runnerTemp: string
2022-06-02 15:53:11 -04:00
constructor() {
2022-06-06 00:21:44 -04:00
this.tempDirPath = `${__dirname}/_temp/runner`
this.runnerWorkdir = `${this.tempDirPath}/_work`
this.runnerTemp = `${this.tempDirPath}/_work/_temp`
this.podName = uuidv4().replace(/-/g, '')
2022-06-02 15:53:11 -04:00
}
2025-07-29 11:06:45 +02:00
async initialize(): Promise<void> {
2022-06-06 00:21:44 -04:00
process.env['ACTIONS_RUNNER_POD_NAME'] = `${this.podName}`
process.env['RUNNER_WORKSPACE'] = `${this.runnerWorkdir}/repo`
process.env['RUNNER_TEMP'] = `${this.runnerTemp}`
process.env['GITHUB_WORKSPACE'] = `${this.runnerWorkdir}/repo/repo`
2022-06-06 00:21:44 -04:00
process.env['ACTIONS_RUNNER_KUBERNETES_NAMESPACE'] = 'default'
fs.mkdirSync(`${this.runnerWorkdir}/repo/repo`, { recursive: true })
fs.mkdirSync(`${this.tempDirPath}/externals`, { recursive: true })
fs.mkdirSync(this.runnerTemp, { recursive: true })
fs.mkdirSync(`${this.runnerTemp}/_github_workflow`, { recursive: true })
fs.mkdirSync(`${this.runnerTemp}/_github_home`, { recursive: true })
fs.mkdirSync(`${this.runnerTemp}/_runner_file_commands`, {
recursive: true
})
fs.copyFileSync(
path.resolve(`${__dirname}/../../../examples/example-script.sh`),
`${this.runnerTemp}/example-script.sh`
)
await this.cleanupK8sResources()
2022-06-06 14:27:06 -04:00
try {
2022-06-06 14:15:14 -04:00
await this.createTestJobPod()
} catch (e) {
2022-06-22 09:20:48 -04:00
console.log(e)
}
2022-06-02 15:53:11 -04:00
}
2025-07-29 11:06:45 +02:00
async cleanup(): Promise<void> {
2022-06-06 00:21:44 -04:00
try {
await this.cleanupK8sResources()
fs.rmSync(this.tempDirPath, { recursive: true })
2025-07-29 11:06:45 +02:00
} catch {
// Ignore errors during cleanup
}
2022-06-06 00:21:44 -04:00
}
2025-07-29 11:06:45 +02:00
async cleanupK8sResources(): Promise<void> {
2022-06-06 00:21:44 -04:00
await k8sApi
2025-07-29 11:06:45 +02:00
.deleteNamespacedPod({
name: this.podName,
namespace: 'default',
gracePeriodSeconds: 0
})
.catch((e: k8s.ApiException<any>) => {
if (e.code !== 404) {
console.error(JSON.stringify(e))
}
2025-07-29 11:06:45 +02:00
})
await k8sApi
.deleteNamespacedPod({
name: `${this.podName}-workflow`,
namespace: 'default',
gracePeriodSeconds: 0
})
.catch((e: k8s.ApiException<any>) => {
if (e.code !== 404) {
console.error(JSON.stringify(e))
}
2025-07-29 11:06:45 +02:00
})
2022-06-02 15:53:11 -04:00
}
2025-07-29 11:06:45 +02:00
createFile(fileName?: string): string {
2022-06-02 15:53:11 -04:00
const filePath = `${this.tempDirPath}/${fileName || uuidv4()}`
fs.writeFileSync(filePath, '')
return filePath
}
2025-07-29 11:06:45 +02:00
removeFile(fileName: string): void {
2022-06-02 15:53:11 -04:00
const filePath = `${this.tempDirPath}/${fileName}`
fs.rmSync(filePath)
}
2022-06-06 00:21:44 -04:00
2025-07-29 11:06:45 +02:00
async createTestJobPod(): Promise<void> {
2022-06-06 00:21:44 -04:00
const container = {
name: 'runner',
image: 'ghcr.io/actions/actions-runner:latest',
2022-06-06 00:21:44 -04:00
imagePullPolicy: 'IfNotPresent'
} as k8s.V1Container
const pod: k8s.V1Pod = {
metadata: {
name: this.podName
},
spec: {
restartPolicy: 'Never',
containers: [container],
securityContext: {
runAsUser: 1001,
runAsGroup: 1001,
fsGroup: 1001
}
2022-06-06 00:21:44 -04:00
}
} as k8s.V1Pod
2025-07-29 11:06:45 +02:00
await k8sApi.createNamespacedPod({ namespace: 'default', body: pod })
2022-06-06 00:21:44 -04:00
}
2025-07-29 11:06:45 +02:00
getPrepareJobDefinition(): HookData {
const prepareJob = JSON.parse(
fs.readFileSync(
path.resolve(__dirname + '/../../../examples/prepare-job.json'),
'utf8'
)
)
prepareJob.args.container.userMountVolumes = undefined
prepareJob.args.container.registry = null
prepareJob.args.services.forEach(s => {
s.registry = null
})
return prepareJob
}
2025-07-29 11:06:45 +02:00
getRunScriptStepDefinition(): HookData {
const runScriptStep = JSON.parse(
fs.readFileSync(
path.resolve(__dirname + '/../../../examples/run-script-step.json'),
'utf8'
)
)
runScriptStep.args.entryPointArgs[1] = `/__w/_temp/example-script.sh`
return runScriptStep
}
2025-07-29 11:06:45 +02:00
getRunContainerStepDefinition(): HookData {
const runContainerStep = JSON.parse(
fs.readFileSync(
path.resolve(__dirname + '/../../../examples/run-container-step.json'),
'utf8'
)
)
runContainerStep.args.entryPointArgs[1] = `/__w/_temp/example-script.sh`
runContainerStep.args.userMountVolumes = undefined
runContainerStep.args.registry = null
return runContainerStep
}
2022-06-02 15:53:11 -04:00
}