Browse Source

chore: oos changes (#9919)

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/9950/head
Mert E. 1 day ago committed by GitHub
parent
commit
615a9c147e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 24
      packages/nc-gui/components/dlg/ColumnUpdateConfirm.vue
  2. 6
      packages/nc-gui/components/smartsheet/header/Menu.vue
  3. 3
      packages/nc-gui/composables/useExtensions.ts
  4. 385
      packages/nc-gui/extensions/data-exporter/index.vue
  5. 4
      packages/nc-gui/extensions/data-exporter/manifest.json
  6. 3
      packages/nc-gui/extensions/json-exporter/manifest.json
  7. 6
      packages/nocodb-sdk/src/lib/import-export-data.ts
  8. 4
      packages/nocodb/src/cache/NocoCache.ts
  9. 3
      packages/nocodb/src/cache/RedisCacheMgr.ts
  10. 3
      packages/nocodb/src/cache/RedisMockCacheMgr.ts
  11. 7
      packages/nocodb/src/models/Integration.spec.ts
  12. 2
      packages/nocodb/src/modules/jobs/jobs.module.ts
  13. 5
      packages/nocodb/src/utils/globals.ts
  14. 19
      scripts/self-hosted-gh-runner/Dockerfile
  15. 50
      scripts/self-hosted-gh-runner/values.yaml

24
packages/nc-gui/components/dlg/ColumnUpdateConfirm.vue

@ -10,13 +10,20 @@ const visible = useVModel(props, 'visible', emit)
</script>
<template>
<GeneralModal v-model:visible="visible" size="small">
<div class="flex flex-col p-6" @click.stop>
<div class="flex flex-row pb-2 mb-4 font-medium text-lg border-b-1 border-gray-50 text-gray-800">Field Type Change</div>
<NcModal v-model:visible="visible" size="small" :show-separator="false" :centered="false">
<template #header>
<div class="flex flex-row items-center gap-x-2">Field Type Change</div>
</template>
<div class="mb-3 text-gray-800">
<div class="flex item-center gap-2 mb-4">
<component :is="iconMap.warning" id="nc-selected-item-icon" class="text-yellow-500 w-10 h-10" />
<div class="flex flex-col" @click.stop>
<div
class="text-gray-800"
:class="{
'mb-3': $slots['entity-preview'],
}"
>
<div class="flex item-center gap-2">
<GeneralIcon id="nc-selected-item-icon" icon="alertTriangle" class="h-10 w-10 text-yellow-500" />
This action cannot be undone. Converting data types may result in data loss. Proceed with caution!
</div>
</div>
@ -24,13 +31,14 @@ const visible = useVModel(props, 'visible', emit)
<slot name="entity-preview"></slot>
<div class="flex flex-row gap-x-2 mt-2.5 pt-2.5 justify-end">
<NcButton type="secondary" @click="visible = false">
<NcButton size="small" type="secondary" @click="visible = false">
{{ $t('general.cancel') }}
</NcButton>
<NcButton
key="submit"
autofocus
size="small"
type="primary"
html-type="submit"
:loading="saving"
@ -42,5 +50,5 @@ const visible = useVModel(props, 'visible', emit)
</NcButton>
</div>
</div>
</GeneralModal>
</NcModal>
</template>

6
packages/nc-gui/components/smartsheet/header/Menu.vue

@ -416,6 +416,10 @@ const onClickCopyFieldUrl = async (field: ColumnType) => {
isFieldIdCopied.value = true
}
const onDeleteColumn = () => {
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
}
</script>
<template>
@ -697,7 +701,7 @@ const onClickCopyFieldUrl = async (field: ColumnType) => {
</NcMenu>
</template>
</a-dropdown>
<SmartsheetHeaderDeleteColumnModal v-model:visible="showDeleteColumnModal" />
<SmartsheetHeaderDeleteColumnModal v-model:visible="showDeleteColumnModal" :on-delete-column="onDeleteColumn" />
<DlgColumnDuplicate
v-if="column"
ref="duplicateDialogRef"

3
packages/nc-gui/composables/useExtensions.ts

@ -24,7 +24,6 @@ export interface ExtensionManifest {
height?: number
}
}
disabled?: boolean
links: {
title: string
href: string
@ -33,6 +32,8 @@ export interface ExtensionManifest {
modalSize?: 'xs' | 'sm' | 'md' | 'lg'
contentMinHeight?: string
}
order: number
disabled?: boolean
}
abstract class ExtensionType {

385
packages/nc-gui/extensions/data-exporter/index.vue

@ -264,6 +264,18 @@ onMounted(async () => {
<template>
<ExtensionsExtensionWrapper>
<template v-if="fullscreen" #headerExtra>
<NcTooltip class="flex" placement="topRight" :disabled="!isExporting">
<template #title> The CSV file is being prepared in the background. You'll be notified once it's ready. </template>
<NcButton
:disabled="!exportPayload?.viewId || isExporting"
:loading="isExporting"
size="small"
@click="exportDataAsync"
>{{ isExporting ? 'Generating' : 'Export' }}</NcButton
>
</NcTooltip>
</template>
<div
ref="dataExporterRef"
class="data-exporter"
@ -272,70 +284,12 @@ onMounted(async () => {
}"
>
<div
v-if="!fullscreen"
class="p-3 flex flex-col gap-3"
:class="{
'bg-white': fullscreen,
}"
>
<div v-if="fullscreen" class="flex items-center gap-3 max-w-full">
<div class="flex flex-col gap-2 w-[calc(50%_-_6px)]">
<div>Separator</div>
<a-form-item class="!my-0 flex-1">
<NcSelect
v-model:value="exportPayload.delimiter"
placeholder="-select separator-"
:disabled="isExporting"
class="nc-data-exporter-separator nc-select-shadow"
dropdown-class-name="w-[180px]"
@change="saveChanges"
>
<a-select-option v-for="delimiter of csvColumnSeparatorOptions" :key="delimiter.value" :value="delimiter.value">
<div class="w-full flex items-center gap-2">
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ delimiter.label }}</template>
<span>{{ delimiter.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.delimiter === delimiter.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
<div class="flex flex-col gap-2 w-[calc(50%_-_6px)]">
<div class="min-w-[65px]">Encoding</div>
<a-form-item class="!my-0 flex-1">
<NcSelect
v-model:value="exportPayload.encoding"
placeholder="-select encoding-"
class="nc-data-exporter-encoding nc-select-shadow"
dropdown-class-name="w-[190px]"
:filter-option="filterOption"
show-search
@change="saveChanges"
>
<a-select-option v-for="encoding of charsetOptions" :key="encoding.label" :value="encoding.value">
<div class="w-full flex items-center gap-2">
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ encoding.label }}</template>
<span>{{ encoding.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.encoding === encoding.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
</div>
<div class="flex items-center justify-between gap-2.5 flex-wrap">
<div
class="nc-data-exporter-select-wrapper flex-1 flex items-center border-1 border-nc-border-gray-medium rounded-lg relative shadow-default"
@ -435,112 +389,245 @@ onMounted(async () => {
</div>
</div>
<div
class="data-exporter-body flex-1 flex flex-col"
class="data-exporter-body flex-1 flex"
:class="{
'rounded-lg border-1 m-3': fullscreen,
'': fullscreen,
'flex-col': !fullscreen,
}"
>
<div class="data-exporter-header">Recent Exports</div>
<div v-if="exportedFiles.length" class="flex-1 flex flex-col nc-scrollbar-thin max-h-[calc(100%_-_25px)]">
<template v-for="exp of exportedFiles">
<div
v-if="exp.status === JobStatus.COMPLETED ? exp.result : true"
:key="exp.id"
class="p-3 flex gap-2 justify-between border-b-1"
:class="{
'px-4 py-3': fullscreen,
'px-3 py-2': !fullscreen,
'bg-white hover:bg-gray-50': exp.status === JobStatus.COMPLETED,
'bg-nc-bg-red-light': exp.status !== JobStatus.COMPLETED,
}"
>
<div
v-if="fullscreen"
class="w-[320px] border-r-1 border-r-nc-border-gray-medium bg-white p-4 pt-t flex flex-col gap-5 nc-scrollbar-thin"
>
<div class="text-base font-bold text-nc-content-gray-extreme">Settings</div>
<div class="flex flex-col gap-2">
<div class="text-nc-content-gray font-medium">Table</div>
<a-form-item class="!my-0">
<NcSelect
v-model:value="exportPayload.tableId"
placeholder="-select table-"
:disabled="isExporting"
class="nc-data-exporter-table-select-sidebar nc-select-shadow"
:filter-option="filterOption"
dropdown-class-name="w-[250px]"
show-search
@change="onTableSelect"
>
<a-select-option v-for="table of tableList" :key="table.label" :value="table.value">
<div class="w-full flex items-center gap-2">
<div class="min-w-5 flex items-center justify-center">
<GeneralTableIcon :meta="{ meta: table.meta }" class="text-gray-500" />
</div>
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ table.label }}</template>
<span>{{ table.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.tableId === table.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
<div class="flex flex-col gap-2">
<div class="text-nc-content-gray font-medium">View</div>
<a-form-item class="!my-0 min-w-1/2">
<NcSelect
v-model:value="exportPayload.viewId"
placeholder="-select view-"
:disabled="isExporting"
class="nc-data-exporter-view-select-sidebar nc-select-shadow"
dropdown-class-name="w-[250px]"
:filter-option="filterOption"
show-search
placement="bottomRight"
@change="onViewSelect"
>
<a-select-option v-for="view of viewList" :key="view.label" :value="view.value">
<div class="w-full flex items-center gap-2">
<div class="min-w-5 flex items-center justify-center">
<GeneralViewIcon :meta="{ meta: view.meta, type: view.type }" class="flex-none text-gray-500" />
</div>
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ view.label }}</template>
<span>{{ view.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.viewId === view.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
<div class="flex flex-col gap-2">
<div>Separator</div>
<a-form-item class="!my-0 flex-1">
<NcSelect
v-model:value="exportPayload.delimiter"
placeholder="-select separator-"
:disabled="isExporting"
class="nc-data-exporter-separator nc-select-shadow"
dropdown-class-name="w-[180px]"
@change="saveChanges"
>
<a-select-option v-for="delimiter of csvColumnSeparatorOptions" :key="delimiter.value" :value="delimiter.value">
<div class="w-full flex items-center gap-2">
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ delimiter.label }}</template>
<span>{{ delimiter.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.delimiter === delimiter.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
<div class="flex flex-col gap-2">
<div class="min-w-[65px]">Encoding</div>
<a-form-item class="!my-0 flex-1">
<NcSelect
v-model:value="exportPayload.encoding"
placeholder="-select encoding-"
class="nc-data-exporter-encoding nc-select-shadow"
dropdown-class-name="w-[190px]"
:filter-option="filterOption"
show-search
@change="saveChanges"
>
<a-select-option v-for="encoding of charsetOptions" :key="encoding.label" :value="encoding.value">
<div class="w-full flex items-center gap-2">
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
<template #title>{{ encoding.label }}</template>
<span>{{ encoding.label }}</span>
</NcTooltip>
<component
:is="iconMap.check"
v-if="exportPayload.encoding === encoding.value"
id="nc-selected-item-icon"
class="flex-none text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</a-form-item>
</div>
</div>
<div class="flex flex-col flex-1 nc-scrollbar-thin">
<div class="data-exporter-header sticky top-0 z-100">Recent Exports</div>
<div v-if="exportedFiles.length" class="flex-1 flex flex-col max-h-[calc(100%_-_25px)]">
<template v-for="exp of exportedFiles">
<div
class="flex-1 flex items-start gap-3"
v-if="exp.status === JobStatus.COMPLETED ? exp.result : true"
:key="exp.id"
class="p-3 flex gap-2 justify-between border-b-1"
:class="{
'max-w-[calc(100%_-_74px)]': exp.status === JobStatus.COMPLETED && !exp.result.isNew,
'max-w-[calc(100%_-_113px)]': exp.status === JobStatus.COMPLETED && exp.result.isNew,
'max-w-[calc(100%_-_48px)]': exp.status !== JobStatus.COMPLETED && !exp.result.isNew,
'max-w-[calc(100%_-_85px)]': exp.status !== JobStatus.COMPLETED && exp.result.isNew,
'px-4 py-3': fullscreen,
'px-3 py-2': !fullscreen,
'bg-white hover:bg-gray-50': exp.status === JobStatus.COMPLETED,
'bg-nc-bg-red-light': exp.status !== JobStatus.COMPLETED,
}"
>
<NcTooltip v-if="[JobStatus.COMPLETED, JobStatus.FAILED].includes(exp.status)" class="flex">
<template #title>
{{ jobStatusTooltip[exp.status] }}
</template>
<GeneralIcon
:icon="exp.status === JobStatus.COMPLETED ? 'circleCheckSolid' : 'alertTriangleSolid'"
class="flex-none h-5 w-5"
:class="{
'!text-green-700': exp.status === JobStatus.COMPLETED,
'!text-red-700': exp.status === JobStatus.FAILED,
}"
/>
</NcTooltip>
<div v-else class="h-5 flex items-center">
<GeneralLoader size="regular" class="flex-none" />
</div>
<div
class="flex-1 flex items-start gap-3"
:class="{
'max-w-[calc(100%_-_74px)]': exp.status === JobStatus.COMPLETED && !exp.result.isNew,
'max-w-[calc(100%_-_113px)]': exp.status === JobStatus.COMPLETED && exp.result.isNew,
'max-w-[calc(100%_-_48px)]': exp.status !== JobStatus.COMPLETED && !exp.result.isNew,
'max-w-[calc(100%_-_85px)]': exp.status !== JobStatus.COMPLETED && exp.result.isNew,
}"
>
<NcTooltip v-if="[JobStatus.COMPLETED, JobStatus.FAILED].includes(exp.status)" class="flex">
<template #title>
{{ jobStatusTooltip[exp.status] }}
</template>
<GeneralIcon
:icon="exp.status === JobStatus.COMPLETED ? 'circleCheckSolid' : 'alertTriangleSolid'"
class="flex-none h-5 w-5"
:class="{
'!text-green-700': exp.status === JobStatus.COMPLETED,
'!text-red-700': exp.status === JobStatus.FAILED,
}"
/>
</NcTooltip>
<div v-else class="h-5 flex items-center">
<GeneralLoader size="regular" class="flex-none" />
</div>
<div class="flex-1 max-w-[calc(100%_-_28px)] flex flex-col gap-1">
<div class="inline-flex gap-1 text-sm text-gray-800 -ml-[1px]">
<span class="inline-flex items-center h-5">
<GeneralIcon icon="file" class="flex-none text-gray-600/80 h-3.5 w-3.5" />
</span>
<NcTooltip class="truncate max-w-[calc(100%_-_20px)]" show-on-truncate-only>
<template #title>
<div class="flex-1 max-w-[calc(100%_-_28px)] flex flex-col gap-1">
<div class="inline-flex gap-1 text-sm text-gray-800 -ml-[1px]">
<span class="inline-flex items-center h-5">
<GeneralIcon icon="file" class="flex-none text-gray-600/80 h-3.5 w-3.5" />
</span>
<NcTooltip class="truncate max-w-[calc(100%_-_20px)]" show-on-truncate-only>
<template #title>
{{ exp.result.title || titleHelper() }}
</template>
{{ exp.result.title || titleHelper() }}
</template>
{{ exp.result.title || titleHelper() }}
</NcTooltip>
</div>
</NcTooltip>
</div>
<div v-if="exp.result.timestamp" name="error" class="text-small leading-[18px] text-nc-content-gray-muted">
{{ timeAgo(dayjs(exp.result.timestamp).toString()) }}
<div v-if="exp.result.timestamp" name="error" class="text-small leading-[18px] text-nc-content-gray-muted">
{{ timeAgo(dayjs(exp.result.timestamp).toString()) }}
</div>
</div>
</div>
</div>
<div v-if="exp.result.isNew" class="flex h-7 flex items-center">
<NcBadge color="green" :border="false" class="!bg-nc-bg-green-light !text-nc-content-green-dark">{{
$t('general.new')
}}</NcBadge>
</div>
<div v-if="exp.status === JobStatus.COMPLETED" class="flex" @click="handleDownload(urlHelper(exp.result.url))">
<NcTooltip class="flex">
<template #title>
{{ $t('general.download') }}
</template>
<NcButton type="secondary" size="xs" class="!px-[5px]">
<div class="flex items-center gap-2">
<GeneralIcon icon="download" />
</div>
</NcButton>
</NcTooltip>
</div>
<div v-if="exp.result.isNew" class="flex h-7 flex items-center">
<NcBadge color="green" :border="false" class="!bg-nc-bg-green-light !text-nc-content-green-dark">{{
$t('general.new')
}}</NcBadge>
</div>
<div v-if="exp.status === JobStatus.COMPLETED" class="flex" @click="handleDownload(urlHelper(exp.result.url))">
<NcTooltip class="flex">
<template #title>
{{ $t('general.download') }}
</template>
<NcButton type="secondary" size="xs" class="!px-[5px]">
<div class="flex items-center gap-2">
<GeneralIcon icon="download" />
</div>
</NcButton>
</NcTooltip>
</div>
<div class="flex">
<NcTooltip class="flex">
<template #title>
{{ $t('general.remove') }}
</template>
<div class="flex">
<NcTooltip class="flex">
<template #title>
{{ $t('general.remove') }}
</template>
<NcButton type="text" size="xs" class="!px-[5px]" @click="onRemoveExportedFile(exp.id)">
<GeneralIcon icon="close" />
</NcButton>
</NcTooltip>
<NcButton type="text" size="xs" class="!px-[5px]" @click="onRemoveExportedFile(exp.id)">
<GeneralIcon icon="close" />
</NcButton>
</NcTooltip>
</div>
</div>
</div>
</template>
</div>
<div v-else class="px-3 py-2 flex-1 flex items-center justify-center text-gray-800">
<a-empty
:image-style="{
height: '24px',
}"
:image="Empty.PRESENTED_IMAGE_SIMPLE"
description="No exports"
class="!my-0"
/>
</template>
</div>
<div v-else class="px-3 py-2 flex-1 flex items-center justify-center text-gray-800">
<a-empty
:image-style="{
height: '24px',
}"
:image="Empty.PRESENTED_IMAGE_SIMPLE"
description="No exports"
class="!my-0"
/>
</div>
</div>
</div>
</div>

4
packages/nc-gui/extensions/data-exporter/manifest.json

@ -23,7 +23,7 @@
}
],
"config": {
"modalSize": "sm",
"contentMinHeight": "310px"
}
},
"order": 2
}

3
packages/nc-gui/extensions/json-exporter/manifest.json

@ -21,5 +21,6 @@
"config": {
"modalSize": "sm",
"contentMinHeight": "198px"
}
},
"order": 3
}

6
packages/nocodb-sdk/src/lib/import-export-data.ts

@ -136,15 +136,15 @@ export enum CsvColumnSeparator {
export const csvColumnSeparatorOptions = [
{
label: ',',
label: 'Comma (,)',
value: CsvColumnSeparator[','],
},
{
label: ';',
label: 'Semi-colon (;)',
value: CsvColumnSeparator[';'],
},
{
label: '|',
label: 'Pipe (|)',
value: CsvColumnSeparator['|'],
},
{

4
packages/nocodb/src/cache/NocoCache.ts vendored

@ -1,7 +1,7 @@
import RedisCacheMgr from './RedisCacheMgr';
import RedisMockCacheMgr from './RedisMockCacheMgr';
import type CacheMgr from './CacheMgr';
import { CacheGetType } from '~/utils/globals';
import { CACHE_PREFIX, CacheGetType } from '~/utils/globals';
export default class NocoCache {
private static client: CacheMgr;
@ -21,7 +21,7 @@ export default class NocoCache {
// TODO(cache): fetch orgs once it's implemented
const orgs = 'noco';
this.prefix = `nc:${orgs}`;
this.prefix = `${CACHE_PREFIX}:${orgs}`;
}
public static async set(key, value): Promise<boolean> {

3
packages/nocodb/src/cache/RedisCacheMgr.ts vendored

@ -1,6 +1,7 @@
import debug from 'debug';
import Redis from 'ioredis';
import CacheMgr from './CacheMgr';
import { CACHE_PREFIX } from '~/utils/globals';
const _log = debug('nc:cache');
@ -22,7 +23,7 @@ export default class RedisCacheMgr extends CacheMgr {
// TODO(cache): fetch orgs once it's implemented
const orgs = 'noco';
this.prefix = `nc:${orgs}`;
this.prefix = `${CACHE_PREFIX}:${orgs}`;
this.context = 'RedisCacheMgr';
}
}

3
packages/nocodb/src/cache/RedisMockCacheMgr.ts vendored

@ -1,6 +1,7 @@
import debug from 'debug';
import Redis from 'ioredis-mock';
import CacheMgr from './CacheMgr';
import { CACHE_PREFIX } from '~/utils/globals';
const _log = debug('nc:cache');
@ -13,7 +14,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
// TODO(cache): fetch orgs once it's implemented
const orgs = 'noco';
this.prefix = `nc:${orgs}`;
this.prefix = `${CACHE_PREFIX}:${orgs}`;
this.context = 'RedisMockCacheMgr';
}
}

7
packages/nocodb/src/models/Integration.spec.ts

@ -106,16 +106,11 @@ describe('Integration Model', () => {
'bypass',
'bypass',
MetaTable.INTEGRATIONS,
isEE ? null : 'test-id',
'test-id',
null,
isEE
? {
_and: [
{
id: {
eq: 'test-id',
},
},
{
_or: [
{

2
packages/nocodb/src/modules/jobs/jobs.module.ts

@ -44,6 +44,7 @@ import { QueueService as FallbackQueueService } from '~/modules/jobs/fallback/fa
import { JOBS_QUEUE } from '~/interface/Jobs';
import { RecoverLinksMigration } from '~/modules/jobs/migration-jobs/nc_job_003_recover_links';
import { CleanupDuplicateColumnMigration } from '~/modules/jobs/migration-jobs/nc_job_004_cleanup_duplicate_column';
import { CACHE_PREFIX } from '~/utils/globals';
export const JobsModuleMetadata = {
imports: [
@ -52,6 +53,7 @@ export const JobsModuleMetadata = {
? [
BullModule.forRoot({
url: process.env.NC_REDIS_JOB_URL,
prefix: CACHE_PREFIX === 'nc' ? undefined : `${CACHE_PREFIX}`,
}),
BullModule.registerQueue({
name: JOBS_QUEUE,

5
packages/nocodb/src/utils/globals.ts

@ -245,3 +245,8 @@ export const RootScopeTables = {
MetaTable.INTEGRATIONS_STORE,
],
};
export const CACHE_PREFIX =
process.env.NC_CACHE_PREFIX && process.env.NC_CACHE_PREFIX.trim().length > 0
? process.env.NC_CACHE_PREFIX
: 'nc';

19
scripts/self-hosted-gh-runner/Dockerfile

@ -0,0 +1,19 @@
FROM ghcr.io/actions/actions-runner:latest
USER root
# Install dependencies
RUN apt-get update && apt-get install -y \
libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev \
libatspi2.0-0 libxshmfence-dev python3 python3-pip curl zip sudo rsync jq \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Node.js (and npm, which includes npx)
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Playwright
RUN npx playwright install --with-deps chromium
USER runner

50
scripts/self-hosted-gh-runner/values.yaml

@ -0,0 +1,50 @@
template:
spec:
initContainers:
- name: init-dind-externals
image: runner:latest
imagePullPolicy: Never
command:
["cp", "-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"]
volumeMounts:
- name: dind-externals
mountPath: /home/runner/tmpDir
containers:
- name: runner
image: runner:latest
imagePullPolicy: Never
command: ["/home/runner/run.sh"]
env:
- name: DOCKER_HOST
value: unix:///run/docker/docker.sock
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: /run/docker
readOnly: true
- name: dind
image: docker:dind
args:
- dockerd
- --host=unix:///run/docker/docker.sock
- --group=$(DOCKER_GROUP_GID)
env:
- name: DOCKER_GROUP_GID
value: "123"
securityContext:
privileged: true
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: /run/docker
- name: dind-externals
mountPath: /home/runner/externals
volumes:
- name: work
emptyDir: {}
- name: dind-sock
emptyDir: {}
- name: dind-externals
emptyDir: {}
Loading…
Cancel
Save