fix(ci): restore custom widget checks
This commit is contained in:
5 files changed
+65
-111
No files matched your search
@@ -312,6 +312,18 @@ jobs:
|
||||
"${PREVIEW_IMAGE}@${AMD64_DIGEST}" \
|
||||
"${PREVIEW_IMAGE}@${ARM64_DIGEST}"
|
||||
|
||||
- name: Verify preview manifest platforms
|
||||
if: "!env.ACT"
|
||||
run: |
|
||||
image="${PREVIEW_IMAGE}:${PREVIEW_TAG}"
|
||||
manifest="$(docker buildx imagetools inspect "$image" --raw)"
|
||||
for architecture in amd64 arm64; do
|
||||
jq --exit-status --arg architecture "$architecture" \
|
||||
'any(.manifests[]; .platform.os == "linux" and .platform.architecture == $architecture)' \
|
||||
<<<"$manifest" >/dev/null
|
||||
done
|
||||
docker buildx imagetools inspect "$image"
|
||||
|
||||
cleanup:
|
||||
name: Clean up preview image
|
||||
if: github.event_name == 'pull_request_target' || (github.event_name == 'workflow_dispatch' && inputs.operation == 'cleanup')
|
||||
|
||||
@@ -105,7 +105,7 @@ External redis is currently not supported with Proxmox Community Scripts
|
||||
The advanced deployments environment variables should only be used if you know what you are doing.
|
||||
:::
|
||||
|
||||
| Environment Variable | Description |
|
||||
| ------------------------ | -------------------------------------------------- |
|
||||
| `DB_MIGRATIONS_DISABLED` | Disable db migrations. For example for helm charts |
|
||||
| Environment Variable | Description |
|
||||
| ------------------------------ | --------------------------------------------------------------------------------------------------------------- |
|
||||
| `DB_MIGRATIONS_DISABLED` | Disable db migrations. For example for helm charts |
|
||||
| `NEXT_PUBLIC_WORKSHOP_API_URL` | Build-time public origin for a separately hosted Workshop PocketBase service. Defaults to `https://homarr.dev`. |
|
||||
@@ -6,13 +6,12 @@ ENV COREPACK_HOME=/corepack
|
||||
RUN mkdir -p /corepack && corepack enable pnpm && corepack install --global pnpm@11.11.0
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json turbo.json ./
|
||||
COPY patches ./patches
|
||||
RUN --mount=type=cache,id=workshop-pnpm-store,target=/pnpm/store pnpm config set store-dir /pnpm/store && pnpm fetch --ignore-scripts
|
||||
COPY apps/docs ./apps/docs
|
||||
COPY packages/custom-widgets ./packages/custom-widgets
|
||||
COPY packages/definitions ./packages/definitions
|
||||
COPY packages/workshop ./packages/workshop
|
||||
COPY tooling/typescript ./tooling/typescript
|
||||
RUN --mount=type=cache,id=workshop-pnpm-store,target=/pnpm/store pnpm install --recursive --offline --frozen-lockfile
|
||||
RUN --mount=type=cache,id=workshop-pnpm-store,target=/pnpm/store pnpm config set store-dir /pnpm/store && pnpm install --filter @homarr/docs... --frozen-lockfile
|
||||
|
||||
FROM dependencies AS website
|
||||
RUN CI=true SKIP_ENV_VALIDATION=true pnpm turbo build --filter=@homarr/docs
|
||||
|
||||
@@ -6862,16 +6862,8 @@
|
||||
"width",
|
||||
"wrapperProps"
|
||||
],
|
||||
"Chip.Group": [
|
||||
"defaultValue",
|
||||
"multiple",
|
||||
"value"
|
||||
],
|
||||
"ChipGroup": [
|
||||
"defaultValue",
|
||||
"multiple",
|
||||
"value"
|
||||
],
|
||||
"Chip.Group": ["defaultValue", "multiple", "value"],
|
||||
"ChipGroup": ["defaultValue", "multiple", "value"],
|
||||
"CloseButton": [
|
||||
"attributes",
|
||||
"bd",
|
||||
@@ -8171,10 +8163,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"CopyButton": [
|
||||
"timeout",
|
||||
"value"
|
||||
],
|
||||
"CopyButton": ["timeout", "value"],
|
||||
"DataList": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -12187,10 +12176,7 @@
|
||||
"withOverlay",
|
||||
"withRoles"
|
||||
],
|
||||
"HoverCard.Target": [
|
||||
"eventPropsWrapperName",
|
||||
"popupType"
|
||||
],
|
||||
"HoverCard.Target": ["eventPropsWrapperName", "popupType"],
|
||||
"HoverCard.Dropdown": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -12346,10 +12332,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"HoverCard.Group": [
|
||||
"closeDelay",
|
||||
"openDelay"
|
||||
],
|
||||
"HoverCard.Group": ["closeDelay", "openDelay"],
|
||||
"HoverCardDropdown": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -12505,14 +12488,8 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"HoverCardGroup": [
|
||||
"closeDelay",
|
||||
"openDelay"
|
||||
],
|
||||
"HoverCardTarget": [
|
||||
"eventPropsWrapperName",
|
||||
"popupType"
|
||||
],
|
||||
"HoverCardGroup": ["closeDelay", "openDelay"],
|
||||
"HoverCardTarget": ["eventPropsWrapperName", "popupType"],
|
||||
"HueSlider": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -15762,10 +15739,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"Menu.CheckboxGroup": [
|
||||
"defaultValue",
|
||||
"value"
|
||||
],
|
||||
"Menu.CheckboxGroup": ["defaultValue", "value"],
|
||||
"Menu.RadioItem": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -15930,18 +15904,9 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"Menu.RadioGroup": [
|
||||
"defaultValue",
|
||||
"value"
|
||||
],
|
||||
"Menu.ContextMenu": [
|
||||
"disabled",
|
||||
"longPressDelay"
|
||||
],
|
||||
"MenuCheckboxGroup": [
|
||||
"defaultValue",
|
||||
"value"
|
||||
],
|
||||
"Menu.RadioGroup": ["defaultValue", "value"],
|
||||
"Menu.ContextMenu": ["disabled", "longPressDelay"],
|
||||
"MenuCheckboxGroup": ["defaultValue", "value"],
|
||||
"MenuCheckboxItem": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -16106,10 +16071,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"MenuContextMenu": [
|
||||
"disabled",
|
||||
"longPressDelay"
|
||||
],
|
||||
"MenuContextMenu": ["disabled", "longPressDelay"],
|
||||
"MenuDivider": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -16638,10 +16600,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"MenuRadioGroup": [
|
||||
"defaultValue",
|
||||
"value"
|
||||
],
|
||||
"MenuRadioGroup": ["defaultValue", "value"],
|
||||
"MenuRadioItem": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -21530,10 +21489,7 @@
|
||||
"withOverlay",
|
||||
"withRoles"
|
||||
],
|
||||
"Popover.Target": [
|
||||
"key",
|
||||
"popupType"
|
||||
],
|
||||
"Popover.Target": ["key", "popupType"],
|
||||
"Popover.Dropdown": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -21689,14 +21645,8 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"Popover.ContextMenu": [
|
||||
"disabled",
|
||||
"longPressDelay"
|
||||
],
|
||||
"PopoverContextMenu": [
|
||||
"disabled",
|
||||
"longPressDelay"
|
||||
],
|
||||
"Popover.ContextMenu": ["disabled", "longPressDelay"],
|
||||
"PopoverContextMenu": ["disabled", "longPressDelay"],
|
||||
"PopoverDropdown": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -21852,10 +21802,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"PopoverTarget": [
|
||||
"key",
|
||||
"popupType"
|
||||
],
|
||||
"PopoverTarget": ["key", "popupType"],
|
||||
"Progress": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -30320,9 +30267,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"Table.DataRenderer": [
|
||||
"data"
|
||||
],
|
||||
"Table.DataRenderer": ["data"],
|
||||
"TableCaption": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -34705,10 +34650,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"Tooltip.Group": [
|
||||
"closeDelay",
|
||||
"openDelay"
|
||||
],
|
||||
"Tooltip.Group": ["closeDelay", "openDelay"],
|
||||
"TooltipFloating": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -34872,10 +34814,7 @@
|
||||
"vocab",
|
||||
"w"
|
||||
],
|
||||
"TooltipGroup": [
|
||||
"closeDelay",
|
||||
"openDelay"
|
||||
],
|
||||
"TooltipGroup": ["closeDelay", "openDelay"],
|
||||
"Tree": [
|
||||
"about",
|
||||
"accessKey",
|
||||
@@ -39832,12 +39771,7 @@
|
||||
"withSuccessStyles",
|
||||
"wrapperProps"
|
||||
],
|
||||
"TimeValue": [
|
||||
"amPmLabels",
|
||||
"format",
|
||||
"value",
|
||||
"withSeconds"
|
||||
],
|
||||
"TimeValue": ["amPmLabels", "format", "value", "withSeconds"],
|
||||
"WeekdaysRow": [
|
||||
"about",
|
||||
"accessKey",
|
||||
|
||||
@@ -6,37 +6,46 @@ import { createLanguageMapping } from "@homarr/translation";
|
||||
|
||||
import { widgetImports } from "..";
|
||||
|
||||
const doesOptionRenderTranslatedCopy = (option: unknown) => {
|
||||
if (typeof option !== "object" || option === null || !("type" in option)) return false;
|
||||
return option.type !== "internal" && option.type !== "customWidgetConfiguration";
|
||||
};
|
||||
|
||||
describe("Widget properties with description should have matching translations", async () => {
|
||||
const enTranslation = await createLanguageMapping().en();
|
||||
objectEntries(widgetImports).forEach(([key, value]) => {
|
||||
Object.entries(value.definition.createOptions({} as SettingsContextProps)).forEach(([optionKey, optionValue_]) => {
|
||||
const optionValue = optionValue_ as { withDescription: boolean };
|
||||
it(`should have matching translations for ${optionKey} option description of ${key} widget`, () => {
|
||||
const option = enTranslation.default.widget[key].option;
|
||||
if (!(optionKey in option)) {
|
||||
throw new Error(`Option ${optionKey} not found in translation`);
|
||||
}
|
||||
const value = option[optionKey as keyof typeof option];
|
||||
Object.entries(value.definition.createOptions({} as SettingsContextProps))
|
||||
.filter(([, option]) => doesOptionRenderTranslatedCopy(option))
|
||||
.forEach(([optionKey, optionValue_]) => {
|
||||
const optionValue = optionValue_ as { withDescription: boolean };
|
||||
it(`should have matching translations for ${optionKey} option description of ${key} widget`, () => {
|
||||
const option = enTranslation.default.widget[key].option;
|
||||
if (!(optionKey in option)) {
|
||||
throw new Error(`Option ${optionKey} not found in translation`);
|
||||
}
|
||||
const value = option[optionKey as keyof typeof option];
|
||||
|
||||
expect("description" in value).toBe(optionValue.withDescription);
|
||||
expect("description" in value).toBe(optionValue.withDescription);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Widget properties should have matching name translations", async () => {
|
||||
const enTranslation = await createLanguageMapping().en();
|
||||
objectEntries(widgetImports).forEach(([key, value]) => {
|
||||
Object.keys(value.definition.createOptions({} as SettingsContextProps)).forEach((optionKey) => {
|
||||
it(`should have matching translations for ${optionKey} option name of ${key} widget`, () => {
|
||||
const option = enTranslation.default.widget[key].option;
|
||||
if (!(optionKey in option)) {
|
||||
throw new Error(`Option ${optionKey} not found in translation`);
|
||||
}
|
||||
const value = option[optionKey as keyof typeof option];
|
||||
Object.entries(value.definition.createOptions({} as SettingsContextProps))
|
||||
.filter(([, option]) => doesOptionRenderTranslatedCopy(option))
|
||||
.forEach(([optionKey]) => {
|
||||
it(`should have matching translations for ${optionKey} option name of ${key} widget`, () => {
|
||||
const option = enTranslation.default.widget[key].option;
|
||||
if (!(optionKey in option)) {
|
||||
throw new Error(`Option ${optionKey} not found in translation`);
|
||||
}
|
||||
const value = option[optionKey as keyof typeof option];
|
||||
|
||||
expect("label" in value).toBe(true);
|
||||
expect("label" in value).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user