Skip to content

Commit fe38e34

Browse files
committed
fix: update paths for plugin build and manifest validation
- Changed the download path in `build-plugin.yml` to point to the `standalone` directory for better organization. - Updated the upload path in `main.yml` to use `web/dist` instead of `web/.nuxt/standalone-apps` for consistency. - Refactored the `findManifestFiles` function in `build-txz.ts` to prioritize checking for `standalone.manifest.json` in the `standalone` subdirectory. - Enhanced the manifest validation logic to ensure proper error handling and file existence checks. This commit improves the build process and ensures that the manifest validation is more robust and organized.
1 parent 75930a4 commit fe38e34

File tree

9 files changed

+529
-48
lines changed

9 files changed

+529
-48
lines changed

.github/workflows/build-plugin.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ jobs:
9999
uses: actions/download-artifact@v5
100100
with:
101101
pattern: unraid-wc-rich
102-
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/nuxt
102+
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/standalone
103103
merge-multiple: true
104104
- name: Download Unraid API
105105
uses: actions/download-artifact@v5

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ jobs:
384384
uses: actions/upload-artifact@v4
385385
with:
386386
name: unraid-wc-rich
387-
path: web/.nuxt/standalone-apps
387+
path: web/dist
388388

389389
build-plugin-staging-pr:
390390
name: Build and Deploy Plugin

api/src/unraid-api/cli/generated/graphql.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -448,20 +448,6 @@ export enum ConfigErrorState {
448448
WITHDRAWN = 'WITHDRAWN'
449449
}
450450

451-
export type ConfigFile = {
452-
__typename?: 'ConfigFile';
453-
content: Scalars['String']['output'];
454-
name: Scalars['String']['output'];
455-
path: Scalars['String']['output'];
456-
/** Human-readable file size (e.g., "1.5 KB", "2.3 MB") */
457-
sizeReadable: Scalars['String']['output'];
458-
};
459-
460-
export type ConfigFilesResponse = {
461-
__typename?: 'ConfigFilesResponse';
462-
files: Array<ConfigFile>;
463-
};
464-
465451
export type Connect = Node & {
466452
__typename?: 'Connect';
467453
/** The status of dynamic remote access */
@@ -553,12 +539,16 @@ export type CoreVersions = {
553539
/** CPU load for a single core */
554540
export type CpuLoad = {
555541
__typename?: 'CpuLoad';
542+
/** The percentage of time the CPU spent running virtual machines (guest). */
543+
percentGuest: Scalars['Float']['output'];
556544
/** The percentage of time the CPU was idle. */
557545
percentIdle: Scalars['Float']['output'];
558546
/** The percentage of time the CPU spent servicing hardware interrupts. */
559547
percentIrq: Scalars['Float']['output'];
560548
/** The percentage of time the CPU spent on low-priority (niced) user space processes. */
561549
percentNice: Scalars['Float']['output'];
550+
/** The percentage of CPU time stolen by the hypervisor. */
551+
percentSteal: Scalars['Float']['output'];
562552
/** The percentage of time the CPU spent in kernel space. */
563553
percentSystem: Scalars['Float']['output'];
564554
/** The total CPU load on a single core, in percent. */
@@ -1645,7 +1635,6 @@ export type PublicPartnerInfo = {
16451635

16461636
export type Query = {
16471637
__typename?: 'Query';
1648-
allConfigFiles: ConfigFilesResponse;
16491638
apiKey?: Maybe<ApiKey>;
16501639
/** All possible permissions for API keys */
16511640
apiKeyPossiblePermissions: Array<Permission>;
@@ -1655,7 +1644,6 @@ export type Query = {
16551644
array: UnraidArray;
16561645
cloud: Cloud;
16571646
config: Config;
1658-
configFile?: Maybe<ConfigFile>;
16591647
connect: Connect;
16601648
customization?: Maybe<Customization>;
16611649
disk: Disk;
@@ -1719,11 +1707,6 @@ export type QueryApiKeyArgs = {
17191707
};
17201708

17211709

1722-
export type QueryConfigFileArgs = {
1723-
name: Scalars['String']['input'];
1724-
};
1725-
1726-
17271710
export type QueryDiskArgs = {
17281711
id: Scalars['PrefixedID']['input'];
17291712
};

plugin/builder/build-txz.ts

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,43 @@ import { cleanupTxzFiles } from "./utils/cleanup";
1010
import { apiDir } from "./utils/paths";
1111
import { getVendorBundleName, getVendorFullPath } from "./build-vendor-store";
1212
import { getAssetUrl } from "./utils/bucket-urls";
13+
import { validateStandaloneManifest, getStandaloneManifestPath } from "./utils/manifest-validator";
1314

1415

15-
// Recursively search for manifest files
16+
// Check for manifest files in expected locations
1617
const findManifestFiles = async (dir: string): Promise<string[]> => {
18+
const files: string[] = [];
19+
20+
// Check standalone subdirectory (preferred)
21+
try {
22+
const standaloneDir = join(dir, "standalone");
23+
const entries = await readdir(standaloneDir, { withFileTypes: true });
24+
for (const entry of entries) {
25+
if (entry.isFile() && entry.name === "standalone.manifest.json") {
26+
files.push("standalone/standalone.manifest.json");
27+
}
28+
}
29+
} catch (error) {
30+
// Directory doesn't exist, continue checking other locations
31+
}
32+
33+
// Check root directory for backwards compatibility
1734
try {
1835
const entries = await readdir(dir, { withFileTypes: true });
19-
const files: string[] = [];
20-
2136
for (const entry of entries) {
22-
const fullPath = join(dir, entry.name);
23-
if (entry.isDirectory()) {
24-
try {
25-
files.push(...(await findManifestFiles(fullPath)));
26-
} catch (error) {
27-
// Log and continue if a subdirectory can't be read
28-
console.warn(`Warning: Could not read directory ${fullPath}: ${error.message}`);
29-
}
30-
} else if (
31-
entry.isFile() &&
32-
entry.name === "standalone.manifest.json"
33-
) {
34-
files.push(entry.name);
37+
if (entry.isFile() && entry.name === "standalone.manifest.json") {
38+
files.push("standalone.manifest.json");
3539
}
3640
}
37-
38-
return files;
3941
} catch (error) {
4042
if (error.code === 'ENOENT') {
4143
console.warn(`Directory does not exist: ${dir}`);
4244
return [];
4345
}
4446
throw error; // Re-throw other errors
4547
}
48+
49+
return files;
4650
};
4751

4852
// Function to store vendor archive information in a recoverable location
@@ -123,16 +127,41 @@ const validateSourceDir = async (validatedEnv: TxzEnv) => {
123127
}
124128

125129
const manifestFiles = await findManifestFiles(webcomponentDir);
126-
const hasStandaloneManifest = manifestFiles.includes("standalone.manifest.json");
130+
const hasStandaloneManifest = manifestFiles.some(file =>
131+
file === "standalone.manifest.json" || file === "standalone/standalone.manifest.json"
132+
);
127133

128134
// Only require standalone.manifest.json for new standalone apps
129135
if (!hasStandaloneManifest) {
130136
console.log("Existing Manifest Files:", manifestFiles);
131137
throw new Error(
132138
`Webcomponents missing required file: standalone.manifest.json - ` +
133-
`run 'pnpm build' in web to generate standalone.manifest.json`
139+
`run 'pnpm build' in web to generate standalone.manifest.json in the standalone/ subdirectory`
134140
);
135141
}
142+
143+
// Validate the manifest contents
144+
const manifestPath = getStandaloneManifestPath(webcomponentDir);
145+
if (manifestPath) {
146+
const validation = await validateStandaloneManifest(manifestPath);
147+
148+
if (!validation.isValid) {
149+
console.error("Standalone manifest validation failed:");
150+
validation.errors.forEach(error => console.error(` ❌ ${error}`));
151+
if (validation.warnings.length > 0) {
152+
console.warn("Warnings:");
153+
validation.warnings.forEach(warning => console.warn(` ⚠️ ${warning}`));
154+
}
155+
throw new Error("Standalone manifest validation failed. See errors above.");
156+
}
157+
158+
if (validation.warnings.length > 0) {
159+
console.warn("Standalone manifest validation warnings:");
160+
validation.warnings.forEach(warning => console.warn(` ⚠️ ${warning}`));
161+
}
162+
163+
console.log("✅ Standalone manifest validation passed");
164+
}
136165

137166
if (!existsSync(apiDir)) {
138167
throw new Error(`API directory ${apiDir} does not exist`);

0 commit comments

Comments
 (0)