Skip to content

Commit 8bf7b35

Browse files
rostalancursoragent
andcommitted
fix(tests): run smoke tests with partial metadata
Allow smoke tests to continue when a workspace has runnable metadata for only some published plugins, and surface skipped plugin metadata gaps in workflow comments. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 37bc297 commit 8bf7b35

3 files changed

Lines changed: 54 additions & 23 deletions

File tree

.github/workflows/workspace-tests.yaml

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ jobs:
125125
if: ${{ needs.resolve.outputs.workspace != '' }}
126126
runs-on: ubuntu-latest
127127
outputs:
128-
plugins-metadata-complete: ${{ steps.build-dynamic-plugins.outputs.plugins-metadata-complete }}
128+
has-runnable-plugins: ${{ steps.build-dynamic-plugins.outputs.has-runnable-plugins }}
129129
skip-tests-missing-env: ${{ steps.build-dynamic-plugins.outputs.skip-tests-missing-env }}
130+
missing-metadata-plugins: ${{ steps.build-dynamic-plugins.outputs.missing-metadata-plugins }}
130131
steps:
131132
- name: Checkout
132133
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -141,16 +142,20 @@ jobs:
141142
PUBLISHED_EXPORTS: ${{ needs.resolve.outputs.published-exports }}
142143
run: |
143144
PLUGINS_FOUND=0
145+
PLUGINS_SKIPPED_MISSING_METADATA=0
144146
PLUGINS_SKIPPED_MISSING_ENV=0
145147
TEST_PLUGINS_SKIPPED=0
146148
TOTAL_PLUGINS=0
147-
PLUGINS_METADATA_COMPLETE="false"
149+
HAS_RUNNABLE_PLUGINS="false"
148150
SKIP_TESTS_MISSING_ENV="false"
151+
MISSING_METADATA_PLUGINS=()
149152
150153
if [ -z "$PUBLISHED_EXPORTS" ]; then
151154
echo "No published exports provided."
152-
echo "plugins-metadata-complete=$PLUGINS_METADATA_COMPLETE" >> "$GITHUB_OUTPUT"
155+
echo "has-runnable-plugins=$HAS_RUNNABLE_PLUGINS" >> "$GITHUB_OUTPUT"
153156
echo "skip-tests-missing-env=$SKIP_TESTS_MISSING_ENV" >> "$GITHUB_OUTPUT"
157+
echo "missing-metadata-plugins<<EOF" >> "$GITHUB_OUTPUT"
158+
echo "EOF" >> "$GITHUB_OUTPUT"
154159
exit 0
155160
fi
156161
@@ -203,14 +208,18 @@ jobs:
203208
echo "Plugin $PLUGIN_NAME is a test plugin without metadata, skipping this individual plugin test"
204209
TEST_PLUGINS_SKIPPED=$((TEST_PLUGINS_SKIPPED + 1))
205210
else
206-
echo "Metadata mapping not found for $PLUGIN_NAME: test workflow will be skipped"
211+
echo "Metadata mapping not found for $PLUGIN_NAME: skipping this plugin"
212+
PLUGINS_SKIPPED_MISSING_METADATA=$((PLUGINS_SKIPPED_MISSING_METADATA + 1))
213+
MISSING_METADATA_PLUGINS+=("$PLUGIN_NAME")
207214
fi
208215
continue
209216
fi
210217
211218
PACKAGE_NAME=$(yq -r '.spec.packageName' "$METADATA_FILE")
212219
if [ -z "$PACKAGE_NAME" ] || [ "$PACKAGE_NAME" = "null" ]; then
213220
echo "spec.packageName not found in $METADATA_FILE, skipping"
221+
PLUGINS_SKIPPED_MISSING_METADATA=$((PLUGINS_SKIPPED_MISSING_METADATA + 1))
222+
MISSING_METADATA_PLUGINS+=("$PLUGIN_NAME")
214223
continue
215224
fi
216225
@@ -264,19 +273,23 @@ jobs:
264273
265274
if [ "$PLUGINS_FOUND" -eq 0 ]; then
266275
echo "[]" >> "$OUT_FILE"
276+
else
277+
HAS_RUNNABLE_PLUGINS="true"
267278
fi
268279
269-
# Check if all plugins were accounted for (found, skipped due to missing env, or test-only)
270-
TOTAL_PROCESSED=$((PLUGINS_FOUND + PLUGINS_SKIPPED_MISSING_ENV + TEST_PLUGINS_SKIPPED))
271280
echo "Plugins: $PLUGINS_FOUND/$TOTAL_PLUGINS processed successfully"
281+
[ "${PLUGINS_SKIPPED_MISSING_METADATA:-0}" -gt 0 ] && echo "Skipped $PLUGINS_SKIPPED_MISSING_METADATA (missing runnable metadata)"
272282
[ "${PLUGINS_SKIPPED_MISSING_ENV:-0}" -gt 0 ] && echo "Skipped $PLUGINS_SKIPPED_MISSING_ENV (missing test.env)"
273-
274-
if [ "$TOTAL_PROCESSED" -eq "$TOTAL_PLUGINS" ] && [ "$TOTAL_PLUGINS" -gt 0 ]; then
275-
PLUGINS_METADATA_COMPLETE="true"
283+
[ "${TEST_PLUGINS_SKIPPED:-0}" -gt 0 ] && echo "Skipped $TEST_PLUGINS_SKIPPED test plugin(s) without metadata"
284+
if [ "${PLUGINS_SKIPPED_MISSING_METADATA:-0}" -gt 0 ]; then
285+
echo "Some published plugins were skipped because they do not have runnable metadata."
276286
fi
277287
278-
echo "plugins-metadata-complete=$PLUGINS_METADATA_COMPLETE" >> "$GITHUB_OUTPUT"
288+
echo "has-runnable-plugins=$HAS_RUNNABLE_PLUGINS" >> "$GITHUB_OUTPUT"
279289
echo "skip-tests-missing-env=$SKIP_TESTS_MISSING_ENV" >> "$GITHUB_OUTPUT"
290+
echo "missing-metadata-plugins<<EOF" >> "$GITHUB_OUTPUT"
291+
printf "%s\n" "${MISSING_METADATA_PLUGINS[@]}" >> "$GITHUB_OUTPUT"
292+
echo "EOF" >> "$GITHUB_OUTPUT"
280293
281294
- name: Upload smoke test artifacts
282295
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -289,13 +302,13 @@ jobs:
289302
needs:
290303
- resolve
291304
- prepare-test-config
292-
if: ${{ needs.prepare-test-config.outputs.plugins-metadata-complete == 'true' && needs.prepare-test-config.outputs.skip-tests-missing-env != 'true' }}
305+
if: ${{ needs.prepare-test-config.outputs.has-runnable-plugins == 'true' && needs.prepare-test-config.outputs.skip-tests-missing-env != 'true' }}
293306
uses: ./.github/workflows/run-workspace-smoke-tests.yaml
294307
with:
295308
target-branch: ${{ needs.resolve.outputs.target-branch }}
296309

297310
add-skipped-test-comment:
298-
if: ${{ always() && needs.resolve.outputs.pr-number != 'null' && needs.resolve.outputs.pr-number != '' && (needs.resolve.outputs.workspace == '' || (needs.prepare-test-config.result != 'skipped' && (needs.prepare-test-config.outputs.plugins-metadata-complete != 'true' || needs.prepare-test-config.outputs.skip-tests-missing-env == 'true'))) }}
311+
if: ${{ always() && needs.resolve.outputs.pr-number != 'null' && needs.resolve.outputs.pr-number != '' && (needs.resolve.outputs.workspace == '' || (needs.prepare-test-config.result != 'skipped' && (needs.prepare-test-config.outputs.has-runnable-plugins != 'true' || needs.prepare-test-config.outputs.skip-tests-missing-env == 'true'))) }}
299312
needs:
300313
- resolve
301314
- prepare-test-config
@@ -310,17 +323,19 @@ jobs:
310323
env:
311324
OVERLAY_COMMIT: ${{ needs.resolve.outputs.overlay-commit }}
312325
INPUT_WORKSPACE: ${{ needs.resolve.outputs.workspace }}
313-
INPUT_PLUGINS_METADATA_COMPLETE: ${{ needs.prepare-test-config.outputs.plugins-metadata-complete || '' }}
326+
INPUT_HAS_RUNNABLE_PLUGINS: ${{ needs.prepare-test-config.outputs.has-runnable-plugins || '' }}
314327
INPUT_SKIP_TESTS_MISSING_ENV: ${{ needs.prepare-test-config.outputs.skip-tests-missing-env || '' }}
328+
INPUT_MISSING_METADATA_PLUGINS: ${{ needs.prepare-test-config.outputs.missing-metadata-plugins || '' }}
315329
INPUT_PR_NUMBER: ${{ needs.resolve.outputs.pr-number }}
316330
with:
317331
script: |
318332
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
319333
const overlayCommit = process.env.OVERLAY_COMMIT;
320334
const pr = Number(core.getInput('pr_number') || '0');
321335
const workspace = core.getInput('workspace');
322-
const pluginsMetadataComplete = core.getInput('plugins_metadata_complete') === 'true';
336+
const hasRunnablePlugins = core.getInput('has_runnable_plugins') === 'true';
323337
const skipTestsMissingEnv = core.getInput('skip_tests_missing_env') === 'true';
338+
const missingMetadataPlugins = (core.getInput('missing_metadata_plugins') || '').trim();
324339
325340
let statusDescription = 'Skipped';
326341
let commentDetail = ' skipped for an unknown reason. Check workflow run for details.\n';
@@ -334,10 +349,15 @@ jobs:
334349
statusDescription = 'Skipped: missing smoke-tests/test.env';
335350
commentDetail = ' skipped: missing workspace `smoke-tests/test.env` file.\n';
336351
summaryDetail = 'Missing workspace `smoke-tests/test.env` file.';
337-
} else if (!pluginsMetadataComplete) {
338-
statusDescription = 'Skipped: missing plugin metadata';
339-
commentDetail = ' skipped: missing plugin metadata files (`<workspace>/metadata/*.yaml`).\n';
340-
summaryDetail = 'Missing plugin metadata files (`<workspace>/metadata/*.yaml`).';
352+
} else if (!hasRunnablePlugins) {
353+
statusDescription = 'Skipped: no runnable plugin metadata';
354+
commentDetail = ' skipped: no published plugins in this workspace have runnable metadata entries.\n';
355+
summaryDetail = 'No published plugins in this workspace have runnable metadata entries.';
356+
}
357+
358+
if (missingMetadataPlugins) {
359+
commentDetail += `\nPublished plugins skipped due to missing runnable metadata:\n\`\`\`\n${missingMetadataPlugins}\n\`\`\`\n`;
360+
summaryDetail += `\n\nPublished plugins skipped due to missing runnable metadata:\n${missingMetadataPlugins}`;
341361
}
342362
343363
if (overlayCommit) {
@@ -367,7 +387,7 @@ jobs:
367387
.write();
368388
369389
add-test-result-comment:
370-
if: ${{ always() && needs.prepare-test-config.outputs.plugins-metadata-complete == 'true' && needs.prepare-test-config.outputs.skip-tests-missing-env != 'true' }}
390+
if: ${{ always() && needs.prepare-test-config.outputs.has-runnable-plugins == 'true' && needs.prepare-test-config.outputs.skip-tests-missing-env != 'true' }}
371391
needs:
372392
- resolve
373393
- prepare-test-config
@@ -389,6 +409,7 @@ jobs:
389409
SUCCESS: ${{ needs.run-smoke-tests.outputs.success }}
390410
FAILED_PLUGINS: ${{ needs.run-smoke-tests.outputs.failed-plugins }}
391411
ERROR_LOGS: ${{ needs.run-smoke-tests.outputs.error-logs }}
412+
MISSING_METADATA_PLUGINS: ${{ needs.prepare-test-config.outputs.missing-metadata-plugins || '' }}
392413
PR_NUMBER: ${{ needs.resolve.outputs.pr-number }}
393414
OVERLAY_COMMIT: ${{ needs.resolve.outputs.overlay-commit }}
394415
with:
@@ -398,6 +419,7 @@ jobs:
398419
const successOutput = process.env.SUCCESS;
399420
const failed = (process.env.FAILED_PLUGINS || '').trim();
400421
const errorLogs = (process.env.ERROR_LOGS || '').trim();
422+
const missingMetadataPlugins = (process.env.MISSING_METADATA_PLUGINS || '').trim();
401423
const pr = Number(process.env.PR_NUMBER);
402424
const overlayCommit = process.env.OVERLAY_COMMIT;
403425
@@ -433,6 +455,9 @@ jobs:
433455
summary += `\n\n<details><summary>Error logs from container</summary>\n\n\`\`\`\n${errorLogs}\n\`\`\`\n\n</details>`;
434456
}
435457
}
458+
if (missingMetadataPlugins) {
459+
summary += `\n\n**Published plugins skipped due to missing runnable metadata:**\n\`\`\`\n${missingMetadataPlugins}\n\`\`\``;
460+
}
436461
await core.summary.addRaw(summary).write();
437462
438463
if (!pr) {
@@ -473,6 +498,9 @@ jobs:
473498
body += `\n\n<details><summary>Error logs from container</summary>\n\n\`\`\`\n${errorLogs}\n\`\`\`\n\n</details>`;
474499
}
475500
}
501+
if (missingMetadataPlugins) {
502+
body += `\n\n:warning: Published plugins skipped due to missing runnable metadata:\n\`\`\`\n${missingMetadataPlugins}\n\`\`\``;
503+
}
476504
477505
await github.rest.issues.createComment({
478506
issue_number: pr,

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ The repository includes an automated smoke testing workflow that verifies plugin
130130

131131
**Prerequisites:**
132132
- PR must touch exactly one workspace
133-
- Each plugin must have its own metadata file in `workspaces/<modified_workspace>/metadata/`
133+
- At least one published plugin in the workspace must have runnable metadata in `workspaces/<modified_workspace>/metadata/`
134+
- Published plugins without runnable metadata are skipped individually
134135

135136
**Triggering smoke tests:**
136137
- After `/publish`: Smoke tests run automatically upon successful publish completion
@@ -139,8 +140,8 @@ The repository includes an automated smoke testing workflow that verifies plugin
139140

140141
**Smoke testing workflow steps:**
141142
1. **Resolve metadata**: Retrieves published OCI references and PR metadata from the `published-exports` artifact
142-
2. **Prepare test config**: Generates `dynamic-plugins.test.yaml` from plugin metadata (each plugin's `spec.appConfigExamples[0].content` is placed under `pluginConfig`) and copies other configuration files - base (`smoke-tests/app-config.yaml` and workspace-specific `app-config.test.yaml` app-config and `test.env`). The optional `app-config.test.yaml` is for test-only or shared workspace settings that should not appear in the user-facing `appConfigExamples` in metadata.
143-
3. **Run smoke tests**: Starts RHDH container with layered configuration, installs dynamic plugins from OCI artifacts, and verifies each plugin loads successfully
143+
2. **Prepare test config**: Generates `dynamic-plugins.test.yaml` from any runnable plugin metadata it finds (each plugin's `spec.appConfigExamples[0].content` is placed under `pluginConfig`) and copies other configuration files - base (`smoke-tests/app-config.yaml` and workspace-specific `app-config.test.yaml` app-config and `test.env`). Published plugins without runnable metadata are skipped; if none are runnable, smoke tests are skipped.
144+
3. **Run smoke tests**: Starts RHDH container with layered configuration, installs dynamic plugins from OCI artifacts, and verifies each plugin included in the generated config loads successfully
144145
4. **Report results**: Posts test status as a commit status check and PR comment with pass/fail results and links to the workflow run
145146

146147
**Environment Variables in Smoke Tests:**

user-guide/01-getting-started.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ This builds and publishes test OCI artifacts tagged as `pr_<number>__<version>`.
278278

279279
After `/publish` completes, smoke tests run automatically if:
280280
- PR touches exactly one workspace
281-
- Each plugin has a metadata file
281+
- At least one published plugin has runnable metadata
282+
283+
Published plugins without runnable metadata are skipped individually. Smoke tests are skipped only when no published plugin in the workspace can produce runnable metadata, or when plugin config references environment variables and the workspace `smoke-tests/test.env` file is missing. If the file exists but required variables are missing from it, the workflow fails instead of skipping.
282284

283285
To re-run smoke tests manually:
284286

0 commit comments

Comments
 (0)