mirror of
https://github.com/actions/runner-container-hooks.git
synced 2025-12-18 19:06:44 +00:00
Compare commits
22 Commits
v0.6.1
...
nikola-jok
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70841b6972 | ||
|
|
1c2ae5d20a | ||
|
|
928f63d88a | ||
|
|
3bda7ef21e | ||
|
|
3b0e87c9a7 | ||
|
|
a7349e7d70 | ||
|
|
ff583c8917 | ||
|
|
e47f9b8af4 | ||
|
|
54e14cb7f3 | ||
|
|
ef2229fc0b | ||
|
|
88dc98f8ef | ||
|
|
b388518d40 | ||
|
|
7afb8f9323 | ||
|
|
d4c5425b22 | ||
|
|
120636d3d7 | ||
|
|
5e805a0546 | ||
|
|
27bae0b2b7 | ||
|
|
8eed1ad1b6 | ||
|
|
7b404841b2 | ||
|
|
977d53963d | ||
|
|
77b40ac6df | ||
|
|
ee10d95fd4 |
@@ -1,4 +0,0 @@
|
|||||||
dist/
|
|
||||||
lib/
|
|
||||||
node_modules/
|
|
||||||
**/tests/**
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["@typescript-eslint"],
|
|
||||||
"extends": ["plugin:github/recommended"],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 9,
|
|
||||||
"sourceType": "module",
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"eslint-comments/no-use": "off",
|
|
||||||
"import/no-namespace": "off",
|
|
||||||
"no-constant-condition": "off",
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"i18n-text/no-en": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": "error",
|
|
||||||
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
|
|
||||||
"@typescript-eslint/no-require-imports": "error",
|
|
||||||
"@typescript-eslint/array-type": "error",
|
|
||||||
"@typescript-eslint/await-thenable": "error",
|
|
||||||
"camelcase": "off",
|
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
|
||||||
"@typescript-eslint/no-array-constructor": "error",
|
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
|
||||||
"@typescript-eslint/no-extraneous-class": "error",
|
|
||||||
"@typescript-eslint/no-floating-promises": "error",
|
|
||||||
"@typescript-eslint/no-for-in-array": "error",
|
|
||||||
"@typescript-eslint/no-inferrable-types": "error",
|
|
||||||
"@typescript-eslint/no-misused-new": "error",
|
|
||||||
"@typescript-eslint/no-namespace": "error",
|
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
||||||
"@typescript-eslint/no-useless-constructor": "error",
|
|
||||||
"@typescript-eslint/no-var-requires": "error",
|
|
||||||
"@typescript-eslint/prefer-for-of": "warn",
|
|
||||||
"@typescript-eslint/prefer-function-type": "warn",
|
|
||||||
"@typescript-eslint/prefer-includes": "error",
|
|
||||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
|
||||||
"@typescript-eslint/promise-function-async": "error",
|
|
||||||
"@typescript-eslint/require-array-sort-compare": "error",
|
|
||||||
"@typescript-eslint/restrict-plus-operands": "error",
|
|
||||||
"semi": "off",
|
|
||||||
"@typescript-eslint/semi": ["error", "never"],
|
|
||||||
"@typescript-eslint/type-annotation-spacing": "error",
|
|
||||||
"@typescript-eslint/unbound-method": "error",
|
|
||||||
"no-shadow": "off",
|
|
||||||
"@typescript-eslint/no-shadow": ["error"]
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es6": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sed -i "s|{{PATHTOREPO}}|$(pwd)|" packages/k8s/tests/test-kind.yaml
|
- run: sed -i "s|{{PATHTOREPO}}|$(pwd)|" packages/k8s/tests/test-kind.yaml
|
||||||
name: Setup kind cluster yaml config
|
name: Setup kind cluster yaml config
|
||||||
- uses: helm/kind-action@v1.2.0
|
- uses: helm/kind-action@v1.2.0
|
||||||
|
|||||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -69,4 +69,4 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
|
|||||||
88
.github/workflows/release.yaml
vendored
88
.github/workflows/release.yaml
vendored
@@ -1,76 +1,70 @@
|
|||||||
name: CD - Release new version
|
name: CD - Release new version
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: npm install
|
|
||||||
name: Install dependencies
|
- name: Install dependencies
|
||||||
- run: npm run bootstrap
|
run: npm install
|
||||||
name: Bootstrap the packages
|
|
||||||
- run: npm run build-all
|
- name: Bootstrap the packages
|
||||||
name: Build packages
|
run: npm run bootstrap
|
||||||
- uses: actions/github-script@v6
|
|
||||||
|
- name: Build packages
|
||||||
|
run: npm run build-all
|
||||||
|
|
||||||
|
- uses: actions/github-script@v7
|
||||||
id: releaseVersion
|
id: releaseVersion
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
result-encoding: string
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const hookVersion = require('./package.json').version
|
return require('./package.json').version
|
||||||
core.setOutput('version', hookVersion);
|
|
||||||
- name: Zip up releases
|
- name: Zip up releases
|
||||||
run: |
|
run: |
|
||||||
zip -r -j actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.version }}.zip packages/docker/dist
|
zip -r -j actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.result }}.zip packages/docker/dist
|
||||||
zip -r -j actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.version }}.zip packages/k8s/dist
|
zip -r -j actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.result }}.zip packages/k8s/dist
|
||||||
|
|
||||||
- name: Calculate SHA
|
- name: Calculate SHA
|
||||||
id: sha
|
id: sha
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sha_docker=$(sha256sum actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.version }}.zip | awk '{print $1}')
|
sha_docker=$(sha256sum actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.result }}.zip | awk '{print $1}')
|
||||||
echo "Docker SHA: $sha_docker"
|
echo "Docker SHA: $sha_docker"
|
||||||
echo "docker-sha=$sha_docker" >> $GITHUB_OUTPUT
|
echo "docker-sha=$sha_docker" >> $GITHUB_OUTPUT
|
||||||
sha_k8s=$(sha256sum actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.version }}.zip | awk '{print $1}')
|
sha_k8s=$(sha256sum actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.result }}.zip | awk '{print $1}')
|
||||||
echo "K8s SHA: $sha_k8s"
|
echo "K8s SHA: $sha_k8s"
|
||||||
echo "k8s-sha=$sha_k8s" >> $GITHUB_OUTPUT
|
echo "k8s-sha=$sha_k8s" >> $GITHUB_OUTPUT
|
||||||
- name: replace SHA
|
|
||||||
|
- name: Create release notes
|
||||||
id: releaseNotes
|
id: releaseNotes
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
var releaseNotes = fs.readFileSync('${{ github.workspace }}/releaseNotes.md', 'utf8').replace(/<HOOK_VERSION>/g, '${{ steps.releaseVersion.outputs.version }}')
|
var releaseNotes = fs.readFileSync('${{ github.workspace }}/releaseNotes.md', 'utf8').replace(/<HOOK_VERSION>/g, '${{ steps.releaseVersion.outputs.result }}')
|
||||||
releaseNotes = releaseNotes.replace(/<DOCKER_SHA>/g, '${{ steps.sha.outputs.docker-sha }}')
|
releaseNotes = releaseNotes.replace(/<DOCKER_SHA>/g, '${{ steps.sha.outputs.docker-sha }}')
|
||||||
releaseNotes = releaseNotes.replace(/<K8S_SHA>/g, '${{ steps.sha.outputs.k8s-sha }}')
|
releaseNotes = releaseNotes.replace(/<K8S_SHA>/g, '${{ steps.sha.outputs.k8s-sha }}')
|
||||||
console.log(releaseNotes)
|
console.log(releaseNotes)
|
||||||
core.setOutput('note', releaseNotes);
|
fs.writeFileSync('${{ github.workspace }}/finalReleaseNotes.md', releaseNotes);
|
||||||
- uses: actions/create-release@v1
|
|
||||||
id: createRelease
|
- name: Create ${{ steps.releaseVersion.outputs.result }} Hook Release
|
||||||
name: Create ${{ steps.releaseVersion.outputs.version }} Hook Release
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
run: |
|
||||||
tag_name: "v${{ steps.releaseVersion.outputs.version }}"
|
gh release create v${{ steps.releaseVersion.outputs.result }} \
|
||||||
release_name: "v${{ steps.releaseVersion.outputs.version }}"
|
--title "v${{ steps.releaseVersion.outputs.result }}" \
|
||||||
body: |
|
--repo ${{ github.repository }} \
|
||||||
${{ steps.releaseNotes.outputs.note }}
|
--notes-file ${{ github.workspace }}/finalReleaseNotes.md \
|
||||||
- name: Upload K8s hooks
|
--latest \
|
||||||
uses: actions/upload-release-asset@v1
|
${{ github.workspace }}/actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.result }}.zip \
|
||||||
env:
|
${{ github.workspace }}/actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.result }}.zip
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.version }}.zip
|
|
||||||
asset_name: actions-runner-hooks-k8s-${{ steps.releaseVersion.outputs.version }}.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
- name: Upload docker hooks
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.version }}.zip
|
|
||||||
asset_name: actions-runner-hooks-docker-${{ steps.releaseVersion.outputs.version }}.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
@@ -1 +1 @@
|
|||||||
* @actions/actions-launch @actions/runner-akvelon
|
* @actions/actions-launch
|
||||||
|
|||||||
82
eslint.config.js
Normal file
82
eslint.config.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
import typescriptEslint from '@typescript-eslint/eslint-plugin'
|
||||||
|
import globals from 'globals'
|
||||||
|
import tsParser from '@typescript-eslint/parser'
|
||||||
|
import github from 'eslint-plugin-github'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['**/dist/', '**/lib/', '**/node_modules/', '**/tests/**/*', 'eslint.config.js']),
|
||||||
|
github.getFlatConfigs().recommended,
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': typescriptEslint
|
||||||
|
},
|
||||||
|
|
||||||
|
files: ['packages/**/*.ts'],
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: globals.node,
|
||||||
|
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: 9,
|
||||||
|
sourceType: 'module',
|
||||||
|
|
||||||
|
parserOptions: {
|
||||||
|
project: './tsconfig.json'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'eslint-comments/no-use': 'off',
|
||||||
|
'import/no-namespace': 'off',
|
||||||
|
'no-constant-condition': 'off',
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'i18n-text/no-en': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': 'error',
|
||||||
|
|
||||||
|
'@typescript-eslint/explicit-member-accessibility': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
accessibility: 'no-public'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
'@typescript-eslint/no-require-imports': 'error',
|
||||||
|
'@typescript-eslint/array-type': 'error',
|
||||||
|
'@typescript-eslint/await-thenable': 'error',
|
||||||
|
camelcase: 'off',
|
||||||
|
|
||||||
|
'@typescript-eslint/explicit-function-return-type': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
allowExpressions: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
'@typescript-eslint/no-array-constructor': 'error',
|
||||||
|
'@typescript-eslint/no-empty-interface': 'error',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
|
'@typescript-eslint/no-extraneous-class': 'error',
|
||||||
|
'@typescript-eslint/no-floating-promises': 'error',
|
||||||
|
'@typescript-eslint/no-for-in-array': 'error',
|
||||||
|
'@typescript-eslint/no-inferrable-types': 'error',
|
||||||
|
'@typescript-eslint/no-misused-new': 'error',
|
||||||
|
'@typescript-eslint/no-namespace': 'error',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'warn',
|
||||||
|
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
||||||
|
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||||
|
'@typescript-eslint/no-useless-constructor': 'error',
|
||||||
|
'@typescript-eslint/no-var-requires': 'error',
|
||||||
|
'@typescript-eslint/prefer-for-of': 'warn',
|
||||||
|
'@typescript-eslint/prefer-function-type': 'warn',
|
||||||
|
'@typescript-eslint/prefer-includes': 'error',
|
||||||
|
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
|
||||||
|
'@typescript-eslint/promise-function-async': 'error',
|
||||||
|
'@typescript-eslint/require-array-sort-compare': 'error',
|
||||||
|
'@typescript-eslint/restrict-plus-operands': 'error',
|
||||||
|
'@typescript-eslint/unbound-method': 'error',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'@typescript-eslint/no-shadow': ['error']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
5699
package-lock.json
generated
5699
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hooks",
|
"name": "hooks",
|
||||||
"version": "0.6.1",
|
"version": "0.6.2",
|
||||||
"description": "Three projects are included - k8s: a kubernetes hook implementation that spins up pods dynamically to run a job - docker: A hook implementation of the runner's docker implementation - A hook lib, which contains shared typescript definitions and utilities that the other packages consume",
|
"description": "Three projects are included - k8s: a kubernetes hook implementation that spins up pods dynamically to run a job - docker: A hook implementation of the runner's docker implementation - A hook lib, which contains shared typescript definitions and utilities that the other packages consume",
|
||||||
"main": "",
|
"main": "",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"bootstrap": "npm install --prefix packages/hooklib && npm install --prefix packages/k8s && npm install --prefix packages/docker",
|
"bootstrap": "npm install --prefix packages/hooklib && npm install --prefix packages/k8s && npm install --prefix packages/docker",
|
||||||
"format": "prettier --write '**/*.ts'",
|
"format": "prettier --write '**/*.ts'",
|
||||||
"format-check": "prettier --check '**/*.ts'",
|
"format-check": "prettier --check '**/*.ts'",
|
||||||
"lint": "eslint packages/**/*.ts",
|
"lint": "eslint",
|
||||||
"build-all": "npm run build --prefix packages/hooklib && npm run build --prefix packages/k8s && npm run build --prefix packages/docker"
|
"build-all": "npm run build --prefix packages/hooklib && npm run build --prefix packages/k8s && npm run build --prefix packages/docker"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -25,12 +25,12 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/actions/runner-container-hooks#readme",
|
"homepage": "https://github.com/actions/runner-container-hooks#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.5.1",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^17.0.23",
|
"@types/node": "^22.14.1",
|
||||||
"@typescript-eslint/parser": "^5.18.0",
|
"@typescript-eslint/parser": "^8.30.1",
|
||||||
"eslint": "^8.12.0",
|
"eslint": "^9.24.0",
|
||||||
"eslint-plugin-github": "^4.3.6",
|
"eslint-plugin-github": "^6.0.0",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^3.5.3",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// eslint-disable-next-line import/no-commonjs
|
|
||||||
module.exports = {
|
|
||||||
clearMocks: true,
|
|
||||||
moduleFileExtensions: ['js', 'ts'],
|
|
||||||
testEnvironment: 'node',
|
|
||||||
testMatch: ['**/*-test.ts'],
|
|
||||||
testRunner: 'jest-circus/runner',
|
|
||||||
transform: {
|
|
||||||
'^.+\\.ts$': 'ts-jest'
|
|
||||||
},
|
|
||||||
setupFilesAfterEnv: ['./jest.setup.js'],
|
|
||||||
verbose: true
|
|
||||||
}
|
|
||||||
12
packages/docker/jest.config.json
Normal file
12
packages/docker/jest.config.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"clearMocks": true,
|
||||||
|
"moduleFileExtensions": ["js", "ts"],
|
||||||
|
"testEnvironment": "node",
|
||||||
|
"testMatch": ["**/*-test.ts"],
|
||||||
|
"testRunner": "jest-circus/runner",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.ts$": "ts-jest"
|
||||||
|
},
|
||||||
|
"verbose": true,
|
||||||
|
"testTimeout": 500000
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
jest.setTimeout(500000)
|
|
||||||
8339
packages/docker/package-lock.json
generated
8339
packages/docker/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,21 +10,21 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1",
|
"@actions/core": "^1.11.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"hooklib": "file:../hooklib",
|
"hooklib": "file:../hooklib",
|
||||||
"shlex": "^2.1.2",
|
"shlex": "^2.1.2",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^17.0.23",
|
"@types/node": "^22.14.1",
|
||||||
"@typescript-eslint/parser": "^5.18.0",
|
"@typescript-eslint/parser": "^8.30.1",
|
||||||
"@vercel/ncc": "^0.33.4",
|
"@vercel/ncc": "^0.38.3",
|
||||||
"jest": "^27.5.1",
|
"jest": "^29.7.0",
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^29.3.2",
|
||||||
"ts-node": "^10.7.0",
|
"ts-node": "^10.9.2",
|
||||||
"tsconfig-paths": "^3.14.1",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,13 @@ export async function prepareJob(
|
|||||||
core.info('No containers exist, skipping hook invocation')
|
core.info('No containers exist, skipping hook invocation')
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
const networkName = generateNetworkName()
|
|
||||||
// Create network
|
let networkName = process.env.ACTIONS_RUNNER_NETWORK_DRIVER
|
||||||
await networkCreate(networkName)
|
if (!networkName) {
|
||||||
|
networkName = generateNetworkName()
|
||||||
|
// Create network
|
||||||
|
await networkCreate(networkName)
|
||||||
|
}
|
||||||
|
|
||||||
// Create Job Container
|
// Create Job Container
|
||||||
let containerMetadata: ContainerMetadata | undefined = undefined
|
let containerMetadata: ContainerMetadata | undefined = undefined
|
||||||
|
|||||||
@@ -45,9 +45,8 @@ export default class TestSetup {
|
|||||||
public initialize(): void {
|
public initialize(): void {
|
||||||
env['GITHUB_WORKSPACE'] = this.workingDirectory
|
env['GITHUB_WORKSPACE'] = this.workingDirectory
|
||||||
env['RUNNER_NAME'] = 'test'
|
env['RUNNER_NAME'] = 'test'
|
||||||
env[
|
env['RUNNER_TEMP'] =
|
||||||
'RUNNER_TEMP'
|
`${this.runnerMockDir}/${this.runnerMockSubdirs.workTemp}`
|
||||||
] = `${this.runnerMockDir}/${this.runnerMockSubdirs.workTemp}`
|
|
||||||
|
|
||||||
for (const dir of this.allTestDirectories) {
|
for (const dir of this.allTestDirectories) {
|
||||||
fs.mkdirSync(dir, { recursive: true })
|
fs.mkdirSync(dir, { recursive: true })
|
||||||
|
|||||||
5373
packages/hooklib/package-lock.json
generated
5373
packages/hooklib/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -14,15 +14,15 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^17.0.23",
|
"@types/node": "^22.14.1",
|
||||||
"@typescript-eslint/parser": "^5.18.0",
|
"@typescript-eslint/parser": "^8.30.1",
|
||||||
"@zeit/ncc": "^0.22.3",
|
"@zeit/ncc": "^0.22.3",
|
||||||
"eslint": "^8.12.0",
|
"eslint": "^9.24.0",
|
||||||
"eslint-plugin-github": "^4.3.6",
|
"eslint-plugin-github": "^6.0.0",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^3.5.3",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^5.8.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1"
|
"@actions/core": "^1.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// eslint-disable-next-line import/no-commonjs
|
|
||||||
module.exports = {
|
|
||||||
clearMocks: true,
|
|
||||||
moduleFileExtensions: ['js', 'ts'],
|
|
||||||
testEnvironment: 'node',
|
|
||||||
testMatch: ['**/*-test.ts'],
|
|
||||||
testRunner: 'jest-circus/runner',
|
|
||||||
transform: {
|
|
||||||
'^.+\\.ts$': 'ts-jest'
|
|
||||||
},
|
|
||||||
setupFilesAfterEnv: ['./jest.setup.js'],
|
|
||||||
verbose: true
|
|
||||||
}
|
|
||||||
12
packages/k8s/jest.config.json
Normal file
12
packages/k8s/jest.config.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"clearMocks": true,
|
||||||
|
"moduleFileExtensions": ["js", "ts"],
|
||||||
|
"testEnvironment": "node",
|
||||||
|
"testMatch": ["**/*-test.ts"],
|
||||||
|
"testRunner": "jest-circus/runner",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.ts$": "ts-jest"
|
||||||
|
},
|
||||||
|
"verbose": true,
|
||||||
|
"testTimeout": 500000
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
jest.setTimeout(500000)
|
|
||||||
8137
packages/k8s/package-lock.json
generated
8137
packages/k8s/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,25 +8,27 @@
|
|||||||
"build": "tsc && npx ncc build",
|
"build": "tsc && npx ncc build",
|
||||||
"format": "prettier --write '**/*.ts'",
|
"format": "prettier --write '**/*.ts'",
|
||||||
"format-check": "prettier --check '**/*.ts'",
|
"format-check": "prettier --check '**/*.ts'",
|
||||||
"lint": "eslint src/**/*.ts"
|
"lint": "eslint src/**/*.ts",
|
||||||
|
"lint:fix": "eslint src/**/*.ts --fix"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1",
|
"@actions/core": "^1.11.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/io": "^1.1.2",
|
"@actions/io": "^1.1.3",
|
||||||
"@kubernetes/client-node": "^0.18.1",
|
"@kubernetes/client-node": "^1.1.2",
|
||||||
"hooklib": "file:../hooklib",
|
"hooklib": "file:../hooklib",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"shlex": "^2.1.2"
|
"shlex": "^2.1.2",
|
||||||
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^17.0.23",
|
"@types/node": "^22.14.1",
|
||||||
"@vercel/ncc": "^0.33.4",
|
"@vercel/ncc": "^0.38.3",
|
||||||
"jest": "^27.5.1",
|
"jest": "^29.7.0",
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^29.3.2",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,13 @@ export async function runContainerStep(
|
|||||||
|
|
||||||
let secretName: string | undefined = undefined
|
let secretName: string | undefined = undefined
|
||||||
if (stepContainer.environmentVariables) {
|
if (stepContainer.environmentVariables) {
|
||||||
secretName = await createSecretForEnvs(stepContainer.environmentVariables)
|
try {
|
||||||
|
secretName = await createSecretForEnvs(stepContainer.environmentVariables)
|
||||||
|
} catch (err) {
|
||||||
|
core.debug(`createSecretForEnvs failed: ${JSON.stringify(err)}`)
|
||||||
|
const message = (err as any)?.response?.body?.message || err
|
||||||
|
throw new Error(`failed to create script environment: ${message}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const extension = readExtensionFromFile()
|
const extension = readExtensionFromFile()
|
||||||
|
|||||||
@@ -95,10 +95,12 @@ export async function createPod(
|
|||||||
appPod.spec.containers = containers
|
appPod.spec.containers = containers
|
||||||
appPod.spec.restartPolicy = 'Never'
|
appPod.spec.restartPolicy = 'Never'
|
||||||
|
|
||||||
if (!useKubeScheduler()) {
|
const nodeName = await getCurrentNodeName()
|
||||||
appPod.spec.nodeName = await getCurrentNodeName()
|
if (useKubeScheduler()) {
|
||||||
|
appPod.spec.affinity = await getPodAffinity(nodeName)
|
||||||
|
} else {
|
||||||
|
appPod.spec.nodeName = nodeName
|
||||||
}
|
}
|
||||||
|
|
||||||
const claimName = getVolumeClaimName()
|
const claimName = getVolumeClaimName()
|
||||||
appPod.spec.volumes = [
|
appPod.spec.volumes = [
|
||||||
{
|
{
|
||||||
@@ -125,8 +127,10 @@ export async function createPod(
|
|||||||
mergePodSpecWithOptions(appPod.spec, extension.spec)
|
mergePodSpecWithOptions(appPod.spec, extension.spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { body } = await k8sApi.createNamespacedPod(namespace(), appPod)
|
return await k8sApi.createNamespacedPod({
|
||||||
return body
|
namespace: namespace(),
|
||||||
|
body: appPod
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createJob(
|
export async function createJob(
|
||||||
@@ -155,8 +159,11 @@ export async function createJob(
|
|||||||
job.spec.template.spec.containers = [container]
|
job.spec.template.spec.containers = [container]
|
||||||
job.spec.template.spec.restartPolicy = 'Never'
|
job.spec.template.spec.restartPolicy = 'Never'
|
||||||
|
|
||||||
if (!useKubeScheduler()) {
|
const nodeName = await getCurrentNodeName()
|
||||||
job.spec.template.spec.nodeName = await getCurrentNodeName()
|
if (useKubeScheduler()) {
|
||||||
|
job.spec.template.spec.affinity = await getPodAffinity(nodeName)
|
||||||
|
} else {
|
||||||
|
job.spec.template.spec.nodeName = nodeName
|
||||||
}
|
}
|
||||||
|
|
||||||
const claimName = getVolumeClaimName()
|
const claimName = getVolumeClaimName()
|
||||||
@@ -178,46 +185,42 @@ export async function createJob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { body } = await k8sBatchV1Api.createNamespacedJob(namespace(), job)
|
return await k8sBatchV1Api.createNamespacedJob({
|
||||||
return body
|
namespace: namespace(),
|
||||||
|
body: job
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getContainerJobPodName(jobName: string): Promise<string> {
|
export async function getContainerJobPodName(jobName: string): Promise<string> {
|
||||||
const selector = `job-name=${jobName}`
|
const selector = `job-name=${jobName}`
|
||||||
const backOffManager = new BackOffManager(60)
|
const backOffManager = new BackOffManager(60)
|
||||||
while (true) {
|
while (true) {
|
||||||
const podList = await k8sApi.listNamespacedPod(
|
const podList = await k8sApi.listNamespacedPod({
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
labelSelector: selector,
|
||||||
undefined,
|
limit: 1
|
||||||
undefined,
|
})
|
||||||
undefined,
|
|
||||||
selector,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!podList.body.items?.length) {
|
if (!podList.items?.length) {
|
||||||
await backOffManager.backOff()
|
await backOffManager.backOff()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!podList.body.items[0].metadata?.name) {
|
if (!podList.items[0].metadata?.name) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed to determine the name of the pod for job ${jobName}`
|
`Failed to determine the name of the pod for job ${jobName}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return podList.body.items[0].metadata.name
|
return podList.items[0].metadata.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deletePod(podName: string): Promise<void> {
|
export async function deletePod(podName: string): Promise<void> {
|
||||||
await k8sApi.deleteNamespacedPod(
|
await k8sApi.deleteNamespacedPod({
|
||||||
podName,
|
name: podName,
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
gracePeriodSeconds: 0
|
||||||
undefined,
|
})
|
||||||
0
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function execPodStep(
|
export async function execPodStep(
|
||||||
@@ -269,7 +272,7 @@ export async function waitForJobToComplete(jobName: string): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`job ${jobName} has failed`)
|
throw new Error(`job ${jobName} has failed: ${JSON.stringify(error)}`)
|
||||||
}
|
}
|
||||||
await backOffManager.backOff()
|
await backOffManager.backOff()
|
||||||
}
|
}
|
||||||
@@ -310,8 +313,10 @@ export async function createDockerSecret(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { body } = await k8sApi.createNamespacedSecret(namespace(), secret)
|
return await k8sApi.createNamespacedSecret({
|
||||||
return body
|
namespace: namespace(),
|
||||||
|
body: secret
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createSecretForEnvs(envs: {
|
export async function createSecretForEnvs(envs: {
|
||||||
@@ -335,30 +340,30 @@ export async function createSecretForEnvs(envs: {
|
|||||||
secret.data[key] = Buffer.from(value).toString('base64')
|
secret.data[key] = Buffer.from(value).toString('base64')
|
||||||
}
|
}
|
||||||
|
|
||||||
await k8sApi.createNamespacedSecret(namespace(), secret)
|
await k8sApi.createNamespacedSecret({ namespace: namespace(), body: secret })
|
||||||
return secretName
|
return secretName
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteSecret(secretName: string): Promise<void> {
|
export async function deleteSecret(secretName: string): Promise<void> {
|
||||||
await k8sApi.deleteNamespacedSecret(secretName, namespace())
|
await k8sApi.deleteNamespacedSecret({
|
||||||
|
name: secretName,
|
||||||
|
namespace: namespace()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pruneSecrets(): Promise<void> {
|
export async function pruneSecrets(): Promise<void> {
|
||||||
const secretList = await k8sApi.listNamespacedSecret(
|
const secretList = await k8sApi.listNamespacedSecret({
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
labelSelector: new RunnerInstanceLabel().toString()
|
||||||
undefined,
|
})
|
||||||
undefined,
|
if (!secretList.items.length) {
|
||||||
undefined,
|
|
||||||
new RunnerInstanceLabel().toString()
|
|
||||||
)
|
|
||||||
if (!secretList.body.items.length) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
secretList.body.items.map(
|
secretList.items.map(
|
||||||
secret => secret.metadata?.name && deleteSecret(secret.metadata.name)
|
async secret =>
|
||||||
|
secret.metadata?.name && deleteSecret(secret.metadata.name)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -386,7 +391,9 @@ export async function waitForPodPhases(
|
|||||||
await backOffManager.backOff()
|
await backOffManager.backOff()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Pod ${podName} is unhealthy with phase status ${phase}`)
|
throw new Error(
|
||||||
|
`Pod ${podName} is unhealthy with phase status ${phase}: ${JSON.stringify(error)}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,8 +424,10 @@ async function getPodPhase(podName: string): Promise<PodPhase> {
|
|||||||
PodPhase.FAILED,
|
PodPhase.FAILED,
|
||||||
PodPhase.UNKNOWN
|
PodPhase.UNKNOWN
|
||||||
])
|
])
|
||||||
const { body } = await k8sApi.readNamespacedPod(podName, namespace())
|
const pod = await k8sApi.readNamespacedPod({
|
||||||
const pod = body
|
name: podName,
|
||||||
|
namespace: namespace()
|
||||||
|
})
|
||||||
|
|
||||||
if (!pod.status?.phase || !podPhaseLookup.has(pod.status.phase)) {
|
if (!pod.status?.phase || !podPhaseLookup.has(pod.status.phase)) {
|
||||||
return PodPhase.UNKNOWN
|
return PodPhase.UNKNOWN
|
||||||
@@ -427,8 +436,10 @@ async function getPodPhase(podName: string): Promise<PodPhase> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function isJobSucceeded(jobName: string): Promise<boolean> {
|
async function isJobSucceeded(jobName: string): Promise<boolean> {
|
||||||
const { body } = await k8sBatchV1Api.readNamespacedJob(jobName, namespace())
|
const job = await k8sBatchV1Api.readNamespacedJob({
|
||||||
const job = body
|
name: jobName,
|
||||||
|
namespace: namespace()
|
||||||
|
})
|
||||||
if (job.status?.failed) {
|
if (job.status?.failed) {
|
||||||
throw new Error(`job ${jobName} has failed`)
|
throw new Error(`job ${jobName} has failed`)
|
||||||
}
|
}
|
||||||
@@ -450,31 +461,26 @@ export async function getPodLogs(
|
|||||||
process.stderr.write(err.message)
|
process.stderr.write(err.message)
|
||||||
})
|
})
|
||||||
|
|
||||||
const r = await log.log(namespace(), podName, containerName, logStream, {
|
await log.log(namespace(), podName, containerName, logStream, {
|
||||||
follow: true,
|
follow: true,
|
||||||
tailLines: 50,
|
|
||||||
pretty: false,
|
pretty: false,
|
||||||
timestamps: false
|
timestamps: false
|
||||||
})
|
})
|
||||||
await new Promise(resolve => r.on('close', () => resolve(null)))
|
await new Promise(resolve => logStream.on('close', () => resolve(null)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prunePods(): Promise<void> {
|
export async function prunePods(): Promise<void> {
|
||||||
const podList = await k8sApi.listNamespacedPod(
|
const podList = await k8sApi.listNamespacedPod({
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
labelSelector: new RunnerInstanceLabel().toString()
|
||||||
undefined,
|
})
|
||||||
undefined,
|
if (!podList.items.length) {
|
||||||
undefined,
|
|
||||||
new RunnerInstanceLabel().toString()
|
|
||||||
)
|
|
||||||
if (!podList.body.items.length) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
podList.body.items.map(
|
podList.items.map(
|
||||||
pod => pod.metadata?.name && deletePod(pod.metadata.name)
|
async pod => pod.metadata?.name && deletePod(pod.metadata.name)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -482,16 +488,13 @@ export async function prunePods(): Promise<void> {
|
|||||||
export async function getPodStatus(
|
export async function getPodStatus(
|
||||||
name: string
|
name: string
|
||||||
): Promise<k8s.V1PodStatus | undefined> {
|
): Promise<k8s.V1PodStatus | undefined> {
|
||||||
const { body } = await k8sApi.readNamespacedPod(name, namespace())
|
const pod = await k8sApi.readNamespacedPod({ name, namespace: namespace() })
|
||||||
return body.status
|
return pod.status
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isAuthPermissionsOK(): Promise<boolean> {
|
export async function isAuthPermissionsOK(): Promise<boolean> {
|
||||||
const sar = new k8s.V1SelfSubjectAccessReview()
|
const sar = new k8s.V1SelfSubjectAccessReview()
|
||||||
const asyncs: Promise<{
|
const asyncs: Promise<k8s.V1SelfSubjectAccessReview>[] = []
|
||||||
response: unknown
|
|
||||||
body: k8s.V1SelfSubjectAccessReview
|
|
||||||
}>[] = []
|
|
||||||
for (const resource of requiredPermissions) {
|
for (const resource of requiredPermissions) {
|
||||||
for (const verb of resource.verbs) {
|
for (const verb of resource.verbs) {
|
||||||
sar.spec = new k8s.V1SelfSubjectAccessReviewSpec()
|
sar.spec = new k8s.V1SelfSubjectAccessReviewSpec()
|
||||||
@@ -501,11 +504,13 @@ export async function isAuthPermissionsOK(): Promise<boolean> {
|
|||||||
sar.spec.resourceAttributes.group = resource.group
|
sar.spec.resourceAttributes.group = resource.group
|
||||||
sar.spec.resourceAttributes.resource = resource.resource
|
sar.spec.resourceAttributes.resource = resource.resource
|
||||||
sar.spec.resourceAttributes.subresource = resource.subresource
|
sar.spec.resourceAttributes.subresource = resource.subresource
|
||||||
asyncs.push(k8sAuthorizationV1Api.createSelfSubjectAccessReview(sar))
|
asyncs.push(
|
||||||
|
k8sAuthorizationV1Api.createSelfSubjectAccessReview({ body: sar })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const responses = await Promise.all(asyncs)
|
const responses = await Promise.all(asyncs)
|
||||||
return responses.every(resp => resp.body.status?.allowed)
|
return responses.every(resp => resp.status?.allowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isPodContainerAlpine(
|
export async function isPodContainerAlpine(
|
||||||
@@ -523,7 +528,7 @@ export async function isPodContainerAlpine(
|
|||||||
podName,
|
podName,
|
||||||
containerName
|
containerName
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch {
|
||||||
isAlpine = false
|
isAlpine = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,15 +536,38 @@ export async function isPodContainerAlpine(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getCurrentNodeName(): Promise<string> {
|
async function getCurrentNodeName(): Promise<string> {
|
||||||
const resp = await k8sApi.readNamespacedPod(getRunnerPodName(), namespace())
|
const resp = await k8sApi.readNamespacedPod({
|
||||||
|
name: getRunnerPodName(),
|
||||||
|
namespace: namespace()
|
||||||
|
})
|
||||||
|
|
||||||
const nodeName = resp.body.spec?.nodeName
|
const nodeName = resp.spec?.nodeName
|
||||||
if (!nodeName) {
|
if (!nodeName) {
|
||||||
throw new Error('Failed to determine node name')
|
throw new Error('Failed to determine node name')
|
||||||
}
|
}
|
||||||
return nodeName
|
return nodeName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPodAffinity(nodeName: string): Promise<k8s.V1Affinity> {
|
||||||
|
const affinity = new k8s.V1Affinity()
|
||||||
|
affinity.nodeAffinity = new k8s.V1NodeAffinity()
|
||||||
|
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution =
|
||||||
|
new k8s.V1NodeSelector()
|
||||||
|
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
matchExpressions: [
|
||||||
|
{
|
||||||
|
key: 'kubernetes.io/hostname',
|
||||||
|
operator: 'In',
|
||||||
|
values: [nodeName]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return affinity
|
||||||
|
}
|
||||||
|
|
||||||
export function namespace(): string {
|
export function namespace(): string {
|
||||||
if (process.env['ACTIONS_RUNNER_KUBERNETES_NAMESPACE']) {
|
if (process.env['ACTIONS_RUNNER_KUBERNETES_NAMESPACE']) {
|
||||||
return process.env['ACTIONS_RUNNER_KUBERNETES_NAMESPACE']
|
return process.env['ACTIONS_RUNNER_KUBERNETES_NAMESPACE']
|
||||||
@@ -623,6 +651,5 @@ export function containerPorts(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getPodByName(name): Promise<k8s.V1Pod> {
|
export async function getPodByName(name): Promise<k8s.V1Pod> {
|
||||||
const { body } = await k8sApi.readNamespacedPod(name, namespace())
|
return await k8sApi.readNamespacedPod({ name, namespace: namespace() })
|
||||||
return body
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ export function containerVolumes(
|
|||||||
mountPath: '/github/file_commands',
|
mountPath: '/github/file_commands',
|
||||||
subPath: '_temp/_runner_file_commands'
|
subPath: '_temp/_runner_file_commands'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: POD_VOLUME_NAME,
|
||||||
|
mountPath: '/github/home',
|
||||||
|
subPath: '_temp/_github_home'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: POD_VOLUME_NAME,
|
name: POD_VOLUME_NAME,
|
||||||
mountPath: '/github/workflow',
|
mountPath: '/github/workflow',
|
||||||
|
|||||||
@@ -32,16 +32,12 @@ describe('Cleanup Job', () => {
|
|||||||
kc.loadFromDefault()
|
kc.loadFromDefault()
|
||||||
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
|
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
|
||||||
|
|
||||||
const podList = await k8sApi.listNamespacedPod(
|
const podList = await k8sApi.listNamespacedPod({
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
labelSelector: new RunnerInstanceLabel().toString()
|
||||||
undefined,
|
})
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
new RunnerInstanceLabel().toString()
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(podList.body.items.length).toBe(0)
|
expect(podList.items.length).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should have no runner linked secrets', async () => {
|
it('should have no runner linked secrets', async () => {
|
||||||
@@ -51,15 +47,11 @@ describe('Cleanup Job', () => {
|
|||||||
kc.loadFromDefault()
|
kc.loadFromDefault()
|
||||||
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
|
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
|
||||||
|
|
||||||
const secretList = await k8sApi.listNamespacedSecret(
|
const secretList = await k8sApi.listNamespacedSecret({
|
||||||
namespace(),
|
namespace: namespace(),
|
||||||
undefined,
|
labelSelector: new RunnerInstanceLabel().toString()
|
||||||
undefined,
|
})
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
new RunnerInstanceLabel().toString()
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(secretList.body.items.length).toBe(0)
|
expect(secretList.items.length).toBe(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!-- ## Features -->
|
<!-- ## Features -->
|
||||||
|
|
||||||
## Bugs
|
<!-- ## Bugs -->
|
||||||
|
|
||||||
- Skip writing extension containers in output context file [#154]
|
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
|
|
||||||
- Bump ws from 7.5.7 to 7.5.10 in /packages/docker [#170]
|
- Bump `@kubernetes/client-node` from 0.18.1 to 0.22.0 in /packages/k8s [#182]
|
||||||
- Bump braces from 3.0.2 to 3.0.3 in /packages/docker [#171]
|
|
||||||
- Bump tar from 6.1.11 to 6.2.1 in /packages/k8s [#156]
|
|
||||||
|
|
||||||
|
|
||||||
## SHA-256 Checksums
|
## SHA-256 Checksums
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user