Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f503f27d3 | ||
|
|
287a0458a1 | ||
|
|
b8af7ebe0e |
Generated
+386
-371
File diff suppressed because it is too large
Load Diff
@@ -13,21 +13,21 @@
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.2",
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"hooklib": "file:../hooklib",
|
||||
"shlex": "^3.0.0",
|
||||
"uuid": "^11.1.0"
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/preset-env": "^7.28.5",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^24.0.14",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.49.0",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"jest": "^30.0.4",
|
||||
"ts-jest": "^29.4.0",
|
||||
"ts-jest": "^29.4.6",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.8.3"
|
||||
|
||||
Generated
+427
-235
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,6 @@
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.2"
|
||||
"@actions/core": "^1.11.1"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+457
-450
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,9 @@
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.2",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/io": "^2.0.0",
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/io": "^1.1.3",
|
||||
"@kubernetes/client-node": "^1.3.0",
|
||||
"hooklib": "file:../hooklib",
|
||||
"js-yaml": "^4.1.0",
|
||||
|
||||
@@ -58,30 +58,14 @@ export async function prepareJob(
|
||||
}
|
||||
|
||||
let services: k8s.V1Container[] = []
|
||||
let serviceNames: string[] = []
|
||||
if (args.services?.length) {
|
||||
const occurrences = new Map<string, number>()
|
||||
for (const s of args.services) {
|
||||
const base = generateContainerName(s.image)
|
||||
occurrences.set(base, (occurrences.get(base) || 0) + 1)
|
||||
}
|
||||
|
||||
const indices = new Map<string, number>()
|
||||
services = args.services.map(service => {
|
||||
const base = generateContainerName(service.image)
|
||||
const total = occurrences.get(base) || 0
|
||||
const idx = indices.get(base) || 0
|
||||
|
||||
let name: string
|
||||
if (total > 1) {
|
||||
name = `${base}-${idx}`
|
||||
} else {
|
||||
name = base
|
||||
}
|
||||
|
||||
indices.set(base, idx + 1)
|
||||
serviceNames.push(name)
|
||||
return createContainerSpec(service, name, false, extension)
|
||||
return createContainerSpec(
|
||||
service,
|
||||
generateContainerName(service.image),
|
||||
false,
|
||||
extension
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -169,15 +153,14 @@ export async function prepareJob(
|
||||
throw new Error(`failed to determine if the pod is alpine: ${message}`)
|
||||
}
|
||||
core.debug(`Setting isAlpine to ${isAlpine}`)
|
||||
generateResponseFile(responseFile, args, createdPod, isAlpine, serviceNames)
|
||||
generateResponseFile(responseFile, args, createdPod, isAlpine)
|
||||
}
|
||||
|
||||
function generateResponseFile(
|
||||
responseFile: string,
|
||||
args: PrepareJobArgs,
|
||||
appPod: k8s.V1Pod,
|
||||
isAlpine: boolean,
|
||||
serviceNames?: string[]
|
||||
isAlpine: boolean
|
||||
): void {
|
||||
if (!appPod.metadata?.name) {
|
||||
throw new Error('app pod must have metadata.name specified')
|
||||
@@ -210,9 +193,7 @@ function generateResponseFile(
|
||||
|
||||
if (args.services?.length) {
|
||||
const serviceContainerNames =
|
||||
serviceNames && serviceNames.length
|
||||
? serviceNames
|
||||
: args.services?.map(s => generateContainerName(s.image)) || []
|
||||
args.services?.map(s => generateContainerName(s.image)) || []
|
||||
|
||||
response.context['services'] = appPod?.spec?.containers
|
||||
?.filter(c => serviceContainerNames.includes(c.name))
|
||||
|
||||
@@ -48,7 +48,6 @@ export async function runScriptStep(
|
||||
'SRC=/__w/_temp_pre',
|
||||
'DST=/__w/_temp',
|
||||
// Overwrite _runner_file_commands
|
||||
'cp -a "$SRC/_runner_file_commands/." "$DST/_runner_file_commands"',
|
||||
`find "$SRC" -type f ! -path "*/_runner_file_commands/*" -exec sh -c '
|
||||
rel="\${1#$2/}"
|
||||
target="$3/$rel"
|
||||
|
||||
@@ -243,37 +243,4 @@ describe('Prepare job', () => {
|
||||
'ghcr.io/actions/actions-runner:latest'
|
||||
)
|
||||
})
|
||||
|
||||
it('should create unique service container names when images collide', async () => {
|
||||
// Use fixed, non-colliding high ports. (Kubernetes hostPort must be unique per node.)
|
||||
prepareJobData.args.container.portMappings = ['31080:8080']
|
||||
|
||||
// make two services with the same image
|
||||
const svc = JSON.parse(JSON.stringify(prepareJobData.args.services[0]))
|
||||
const svc2 = JSON.parse(JSON.stringify(svc))
|
||||
// Ensure unique host ports so the pod spec is valid even with two services.
|
||||
// (Kubernetes hostPort must be unique per node.)
|
||||
svc.portMappings = ['31081:80', '31082:8080']
|
||||
svc2.portMappings = ['31083:80', '31084:8080']
|
||||
prepareJobData.args.services = [svc, svc2]
|
||||
// ensure registries are null as TestHelper expects
|
||||
prepareJobData.args.services.forEach((s: any) => (s.registry = null))
|
||||
|
||||
await expect(
|
||||
prepareJob(prepareJobData.args, prepareJobOutputFilePath)
|
||||
).resolves.not.toThrow()
|
||||
|
||||
const content = JSON.parse(
|
||||
fs.readFileSync(prepareJobOutputFilePath).toString()
|
||||
)
|
||||
|
||||
expect(content.context.services).toBeTruthy()
|
||||
expect(content.context.services.length).toBe(2)
|
||||
|
||||
const got = await getPodByName(content.state.jobPod)
|
||||
const names = (got.spec?.containers || []).map(c => c.name)
|
||||
|
||||
// when images collide, names should be suffixed with -0, -1
|
||||
expect(names).toEqual(expect.arrayContaining(['redis-0', 'redis-1']))
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user