Skip to content

feat(orchestrator): community plugin validation — scheduled compile and build checks - #804

Closed
frostebite wants to merge 3 commits into
mainfrom
feature/community-plugin-validation
Closed

feat(orchestrator): community plugin validation — scheduled compile and build checks#804
frostebite wants to merge 3 commits into
mainfrom
feature/community-plugin-validation

Conversation

@frostebite

@frostebite frostebite commented Mar 5, 2026

Copy link
Copy Markdown
Member

Summary

Implements scheduled CI workflow for validating community Unity packages (#800).

  • Plugin Registry (community-plugins.yml): YAML file where community members can submit PRs to add their packages for automated validation
  • Validation Workflow: Runs weekly (Sunday 02:00 UTC) or on-demand. Creates a minimal Unity project, adds each plugin, and builds with unity-builder
  • Matrix Expansion: Each plugin is tested across its specified platforms
  • Failure Reporting: Automatically creates/updates GitHub issues when validations fail

Manual Trigger

The workflow supports workflow_dispatch with optional filters:

  • plugin_filter: Regex to test specific plugins
  • unity_version: Override the Unity version for all plugins

Closes #800

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added an automated validation workflow for community plugins (weekly + manual) that runs matrixed Unity tests and produces a consolidated validation report and failure issues.
    • Added a community plugin registry configuration to declare plugins, platforms, Unity versions, and timeouts.
    • Updated macOS build workflow to continue on error so a single platform failure won’t block overall runs.

Tracking:

Add scheduled workflow that validates community Unity packages compile
and build correctly using unity-builder. Runs weekly on Sunday.

Includes:
- YAML plugin registry (community-plugins.yml) for package listings
- Matrix expansion across plugins and platforms
- Automatic failure reporting via GitHub issues
- Manual trigger with plugin filter and Unity version override

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Mar 5, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e9e2f428-e2a5-4307-9ec5-92dda0afcf62

📥 Commits

Reviewing files that changed from the base of the PR and between fe2c494 and c112e85.

⛔ Files ignored due to path filters (2)
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
📒 Files selected for processing (4)
  • .github/workflows/orchestrator-async-checks.yml
  • src/model/orchestrator/tests/e2e/orchestrator-end2end-caching.test.ts
  • src/model/orchestrator/workflows/async-workflow.ts
  • src/model/orchestrator/workflows/build-automation-workflow.ts

📝 Walkthrough

Walkthrough

Adds a scheduled/manual GitHub Actions workflow to validate community Unity plugins from a new registry; introduces the registry file; adjusts macOS CI to continue on error; and updates several orchestrator-related clone fallbacks and test configs to use main instead of orchestrator-develop.

Changes

Cohort / File(s) Summary
Community Plugin Validation Workflow
​.github/workflows/validate-community-plugins.yml
New weekly + manual workflow that loads community-plugins.yml, optionally filters plugins, expands a matrix across plugins × platforms × Unity versions, creates minimal Unity test projects, runs builds via the unity-builder action, writes workflow summary + consolidated Validation Report, and creates/updates an open GitHub issue for failures labeled community-plugin-validation.
Plugin Registry
community-plugins.yml
New YAML registry listing community plugins with fields: name, package (UPM/git), source (git/upm/asset-store), unity (min version, default 2021.3), platforms (default [StandaloneLinux64]), and timeout (minutes, default 30).
macOS CI tweak
.github/workflows/build-tests-mac.yml
Adds continue-on-error: true to the buildForAllPlatformsMacOS job.
Orchestrator workflow clone fallback changes
​.github/workflows/orchestrator-async-checks.yml, src/model/orchestrator/workflows/async-workflow.ts, src/model/orchestrator/workflows/build-automation-workflow.ts
Replaced/removes orchestrator-develop fallback and now prefer main; simplified fallback clone logic to try -b main then a generic clone if branch missing.
End-to-end test config
src/model/orchestrator/tests/e2e/orchestrator-end2end-caching.test.ts
Updated test configuration to use main instead of orchestrator-develop for orchestratorBranch.

Sequence Diagram(s)

sequenceDiagram
  participant Trigger as "User / Scheduler"
  participant GH as "GitHub Actions"
  participant Registry as "community-plugins.yml (Registry)"
  participant Matrix as "Matrix Expander"
  participant Builder as "Unity Builder Action"
  participant Report as "Validation Report"
  participant Issues as "GitHub Issues"

  Trigger->>GH: dispatch / cron
  GH->>Registry: load registry
  GH->>Matrix: expand plugins × platforms × unity versions
  Matrix->>Builder: for each matrix entry, create minimal project & build
  Builder-->>GH: build result (success/failure)
  GH->>Report: record results to workflow summary
  GH->>Issues: create/update failure issue with summary & run link
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • webbertakken
  • davidmfinol

Poem

🐰 I hop through YAML in the night,

I spin up builds to make things right,
Matrix hops and Unity spins,
Reports and issues track our wins,
A carrot code review for every green light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: implementing community plugin validation with scheduled CI checks for the orchestrator.
Description check ✅ Passed The description covers main changes, related issues, and includes a checklist, though it lacks workflow run links and has some template sections incomplete.
Linked Issues check ✅ Passed The PR implements the core requirements from #800: a plugin registry (community-plugins.yml), scheduled validation workflow, matrix expansion across platforms, and failure reporting via GitHub issues.
Out of Scope Changes check ✅ Passed The PR includes branch reference updates (orchestrator-develop to main) in workflows and tests that appear to be foundational changes supporting the new validation workflow, not out-of-scope additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/community-plugin-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
community-plugins.yml (1)

6-11: Consider adding an explicit id field (UPM package name) to each plugin entry.

Using a human-readable name as the install key downstream is brittle. A dedicated machine ID makes manifest injection deterministic and avoids name-format edge cases.

Proposed schema update
 #   - name: Human-readable name
+#     id: UPM package identifier used as manifest dependency key (e.g. com.example.plugin)
 #     package: UPM package name or git URL
 #     source: upm | git | asset-store

Also applies to: 15-27

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@community-plugins.yml` around lines 6 - 11, Add an explicit machine-readable
id field to each plugin entry in community-plugins.yml (alongside the existing
name and package fields) and update any manifest injection logic to use this id
as the install key instead of the human-readable name; ensure the id follows the
UPM package naming convention (e.g., scope.package) and is unique per entry, and
update code that references 'name' for installation to reference 'id' (search
for places handling 'name' in manifest injection and package lookup and switch
them to use 'id' and fall back to 'package' only if id is missing).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/validate-community-plugins.yml:
- Line 71: The job name currently uses the template name: '${{ matrix.name }}
(${{ matrix.platform }})' which doesn't include the required 'validate' prefix
so the failure-aggregation script (which builds validateJobs by filtering for
jobs whose names start with 'validate') matches nothing; update the job name
template to include that prefix (e.g., 'validate - ${{ matrix.name }} (${{
matrix.platform }})') and also remove or disable continue-on-error: true on the
build step so real failures surface; alternatively, if you prefer not to rename
jobs, change the aggregation filter to match the existing name pattern, but the
straightforward fix is to prepend 'validate' to the job name and stop continuing
on error so validateJobs and failed counts reflect actual build results.
- Around line 89-108: The current conditional only injects the plugin into
test-project Packages/manifest.json when matrix.source == "git", so upm and
asset-store cases aren't actually tested; update the conditional that checks
matrix.source to also include "upm" (treating it the same as "git" by creating
the manifest and adding the dependency using matrix.name and matrix.package),
and add explicit handling for "asset-store" (either fail the job early with a
clear message or add the proper asset-store installation steps) so the workflow
does not silently run validations without the plugin present.
- Around line 52-60: The matrix construction currently exposes plugin.name and
plugin.package to inline Python interpolation which enables code injection; add
a unique id field to each plugin in community-plugins.yml (e.g., plugin.id),
include id: plugin.id in the matrix push where name/package/unity/platform are
set, and update the manifest-modification step to use the environment-variable
pattern with matrix.id (instead of interpolating matrix.name) when invoking the
Python script so the Python code reads the safe env var rather than executing
inline strings; ensure all places that previously used matrix.name for
interpolation (including the other occurrence) are switched to matrix.id and
that the new id is populated for every plugin entry.
- Around line 18-21: The workflow permissions are missing actions: read which is
required by github.rest.actions.listJobsForWorkflowRun(); update the permissions
block to include actions: read alongside contents: read and issues: write so the
report job can call the Actions API without a 403 (i.e., add the permission
entry "actions: read" in the same permissions mapping).

---

Nitpick comments:
In `@community-plugins.yml`:
- Around line 6-11: Add an explicit machine-readable id field to each plugin
entry in community-plugins.yml (alongside the existing name and package fields)
and update any manifest injection logic to use this id as the install key
instead of the human-readable name; ensure the id follows the UPM package naming
convention (e.g., scope.package) and is unique per entry, and update code that
references 'name' for installation to reference 'id' (search for places handling
'name' in manifest injection and package lookup and switch them to use 'id' and
fall back to 'package' only if id is missing).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 971d1799-3c4a-450b-bafa-7a699deed1c9

📥 Commits

Reviewing files that changed from the base of the PR and between 9d47543 and ccbe1bc.

⛔ Files ignored due to path filters (1)
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
📒 Files selected for processing (2)
  • .github/workflows/validate-community-plugins.yml
  • community-plugins.yml

Comment on lines +18 to +21
permissions:
contents: read
issues: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd validate-community-plugins.yml

Repository: game-ci/unity-builder

Length of output: 47


🏁 Script executed:

cat -n .github/workflows/validate-community-plugins.yml | head -200

Repository: game-ci/unity-builder

Length of output: 8768


🌐 Web query:

GitHub Actions listJobsForWorkflowRun API required permissions scope

💡 Result:

For REST API “List jobs for a workflow run” (GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs):

  • Repo access: anyone with read access to the repository can call it. [1]
  • PAT (classic): for a private repo, the token needs the repo scope. [1]
  • Fine-grained PAT / GitHub App tokens: need Repository permissions → Actions: Read. [1][2]
  • Public repos: can be called without authentication if you’re only accessing public resources. [1]

If calling from within a workflow using GITHUB_TOKEN: set workflow/job permissions to at least:

permissions:
  actions: read

(because the endpoint requires “Actions” read). [1]

Sources: [1] GitHub Docs – REST API endpoints for workflow jobs (List jobs for a workflow run) (docs.github.com), [2] GitHub Docs – Permissions required for GitHub Apps (Actions run/jobs endpoints are “read”) (docs.github.com)

Citations:


Add actions: read permission for the report API call.

The report job calls github.rest.actions.listJobsForWorkflowRun() to fetch job results. This endpoint requires the actions: read permission; without it, the API call will fail with a 403 error and break the validation summary and issue reporting.

Proposed fix
 permissions:
+  actions: read
   contents: read
   issues: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
issues: write
permissions:
actions: read
contents: read
issues: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-community-plugins.yml around lines 18 - 21, The
workflow permissions are missing actions: read which is required by
github.rest.actions.listJobsForWorkflowRun(); update the permissions block to
include actions: read alongside contents: read and issues: write so the report
job can call the Actions API without a 403 (i.e., add the permission entry
"actions: read" in the same permissions mapping).

Comment on lines +52 to +60
for (const plugin of plugins) {
const platforms = plugin.platforms || ['StandaloneLinux64'];
for (const platform of platforms) {
matrix.push({
name: plugin.name,
package: plugin.package,
source: plugin.source || 'git',
unity: '${{ github.event.inputs.unity_version }}' || plugin.unity || '2021.3',
platform: platform,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat .github/workflows/validate-community-plugins.yml

Repository: game-ci/unity-builder

Length of output: 7418


🏁 Script executed:

cat community-plugins.yml

Repository: game-ci/unity-builder

Length of output: 1096


🏁 Script executed:

grep -n "matrix\\.name\|matrix\\.package" .github/workflows/validate-community-plugins.yml

Repository: game-ci/unity-builder

Length of output: 384


Prevent code injection in manifest modification by using environment variables instead of inline Python interpolation.

At line 104, matrix.name and matrix.package are directly interpolated into Python code, creating a code injection vulnerability. A malicious plugin registry entry could inject arbitrary Python commands. The proposed fix using environment variables is correct, but requires adding an id field to the plugin schema in community-plugins.yml to uniquely identify each package.

The fix should:

  1. Add id field to each plugin entry in community-plugins.yml (unique identifier for the package)
  2. Include id: plugin.id in the matrix at lines 52-60
  3. Replace the inline Python string interpolation (line 104) with the environment variable approach shown, using matrix.id instead of matrix.name

Also applies to: 99-106

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-community-plugins.yml around lines 52 - 60, The
matrix construction currently exposes plugin.name and plugin.package to inline
Python interpolation which enables code injection; add a unique id field to each
plugin in community-plugins.yml (e.g., plugin.id), include id: plugin.id in the
matrix push where name/package/unity/platform are set, and update the
manifest-modification step to use the environment-variable pattern with
matrix.id (instead of interpolating matrix.name) when invoking the Python script
so the Python code reads the safe env var rather than executing inline strings;
ensure all places that previously used matrix.name for interpolation (including
the other occurrence) are switched to matrix.id and that the new id is populated
for every plugin entry.

console.log(`Found ${matrix.length} plugin-platform combinations to validate`);

validate:
name: '${{ matrix.name }} (${{ matrix.platform }})'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/validate-community-plugins.yml | head -80

Repository: game-ci/unity-builder

Length of output: 3189


🏁 Script executed:

cat -n .github/workflows/validate-community-plugins.yml | sed -n '60,130p'

Repository: game-ci/unity-builder

Length of output: 2985


🏁 Script executed:

cat -n .github/workflows/validate-community-plugins.yml | sed -n '150,170p'

Repository: game-ci/unity-builder

Length of output: 1244


🏁 Script executed:

# Find the filtering logic in the workflow
rg "validateJobs" -A 2 -B 2 .github/workflows/

Repository: game-ci/unity-builder

Length of output: 1384


Fix job naming and filter mismatch that disconnects validation reporting from actual build failures.

Job names are set to ${{ matrix.name }} (${{ matrix.platform }}) which don't include a validate prefix, but the failure aggregation script filters for jobs starting with validate. This causes the filter to match zero jobs, making validateJobs an empty array and forcing failed to always be 0, which suppresses issue creation even when builds fail. Combined with continue-on-error: true on the build step, actual failures are hidden from the validation report.

Update the job name prefix and corresponding filter:

Proposed fix
-    name: '${{ matrix.name }} (${{ matrix.platform }})'
+    name: 'validate: ${{ matrix.name }} (${{ matrix.platform }})'
@@
-        continue-on-error: true
@@
-            const validateJobs = run.jobs.filter(j => j.name.startsWith('validate'));
+            const validateJobs = run.jobs.filter(j => j.name.startsWith('validate: '));

Also applies to: 122-122, 159-162

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-community-plugins.yml at line 71, The job name
currently uses the template name: '${{ matrix.name }} (${{ matrix.platform }})'
which doesn't include the required 'validate' prefix so the failure-aggregation
script (which builds validateJobs by filtering for jobs whose names start with
'validate') matches nothing; update the job name template to include that prefix
(e.g., 'validate - ${{ matrix.name }} (${{ matrix.platform }})') and also remove
or disable continue-on-error: true on the build step so real failures surface;
alternatively, if you prefer not to rename jobs, change the aggregation filter
to match the existing name pattern, but the straightforward fix is to prepend
'validate' to the job name and stop continuing on error so validateJobs and
failed counts reflect actual build results.

Comment on lines +89 to +108
if [ "${{ matrix.source }}" = "git" ]; then
cat > test-project/Packages/manifest.json << 'MANIFEST'
{
"dependencies": {
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
}
MANIFEST

# Add git package via manifest
cd test-project
cat Packages/manifest.json | python3 -c "
import sys, json
manifest = json.load(sys.stdin)
manifest['dependencies']['${{ matrix.name }}'] = '${{ matrix.package }}'
json.dump(manifest, sys.stdout, indent=2)
" > Packages/manifest.tmp && mv Packages/manifest.tmp Packages/manifest.json
cd ..
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -name "validate-community-plugins.yml" -type f

Repository: game-ci/unity-builder

Length of output: 115


🏁 Script executed:

cat -n ./.github/workflows/validate-community-plugins.yml

Repository: game-ci/unity-builder

Length of output: 8839


upm and asset-store sources are not properly validated in this step.

The conditional at line 89 only injects the plugin dependency for source == "git". For upm and asset-store sources, no manifest is created, so the build validation runs without the plugin actually being added to the test project. This produces a false signal — the build may pass or fail, but it's not testing the plugin itself.

The upm source should be handled the same way as git (added to manifest), while asset-store should either be explicitly unsupported or require different handling.

Proposed fix
-          if [ "${{ matrix.source }}" = "git" ]; then
+          case "${{ matrix.source }}" in
+            git|upm)
             cat > test-project/Packages/manifest.json << 'MANIFEST'
           {
             "dependencies": {
               "com.unity.modules.imgui": "1.0.0",
               "com.unity.modules.jsonserialize": "1.0.0"
             }
           }
           MANIFEST
@@
-            cd ..
-          fi
+            cd ..
+            ;;
+            asset-store)
+              echo "::error::asset-store source is not supported by this automation path yet"
+              exit 1
+              ;;
+            *)
+              echo "::error::Unknown plugin source: ${{ matrix.source }}"
+              exit 1
+              ;;
+          esac
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-community-plugins.yml around lines 89 - 108, The
current conditional only injects the plugin into test-project
Packages/manifest.json when matrix.source == "git", so upm and asset-store cases
aren't actually tested; update the conditional that checks matrix.source to also
include "upm" (treating it the same as "git" by creating the manifest and adding
the dependency using matrix.name and matrix.package), and add explicit handling
for "asset-store" (either fail the job early with a clear message or add the
proper asset-store installation steps) so the workflow does not silently run
validations without the plugin present.

@frostebite frostebite changed the title feat: Community Plugin Validation workflow feat(orchestrator): community plugin validation — scheduled compile and build checks Mar 5, 2026
@frostebite frostebite added enhancement New feature or request orchestrator Orchestrator module Next-Gen Orchestrator Next-Gen experimental features labels Mar 5, 2026
@github-actions

github-actions Bot commented Mar 5, 2026

Copy link
Copy Markdown

Cat Gif

@codecov

codecov Bot commented Mar 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 31.25%. Comparing base (9d47543) to head (c112e85).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #804   +/-   ##
=======================================
  Coverage   31.25%   31.25%           
=======================================
  Files          84       84           
  Lines        4563     4563           
  Branches     1103     1103           
=======================================
  Hits         1426     1426           
  Misses       3137     3137           
Files with missing lines Coverage Δ
src/model/orchestrator/workflows/async-workflow.ts 27.77% <ø> (ø)
...rchestrator/workflows/build-automation-workflow.ts 10.44% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build-tests-mac.yml:
- Line 15: Remove the job-level continue-on-error: true (the top-level
continue-on-error key applied to the macOS job) and instead add
continue-on-error: true to the specific build/test step(s) that run the actual
build and test commands (the same step(s) where the retry-on-failure pattern is
used in the Ubuntu/Windows workflows); keep the matrix intact but ensure the
job-level tolerance is removed so persistent failures bubble up, and replicate
the retry-on-failure step configuration from the other platform workflows so
only the targeted step(s) tolerate transient failures.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c3268c01-3042-43b5-b453-7128bfb737ce

📥 Commits

Reviewing files that changed from the base of the PR and between ccbe1bc and fe2c494.

📒 Files selected for processing (1)
  • .github/workflows/build-tests-mac.yml

buildForAllPlatformsMacOS:
name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
runs-on: macos-latest
continue-on-error: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub Actions jobs continue-on-error job level vs step level behavioral difference workflow fail

💡 Result:

continue-on-error at step level (jobs.<job_id>.steps[*].continue-on-error)

  • Scope: Only that step. The job keeps running subsequent steps even if the step fails.
  • Job/workflow result: The job can still end up “successful” even though the step failed (“allow this step to fail without failing the job”). [1]
  • How to detect the real failure later: A failed continue-on-error step has:
    • steps.<id>.outcome == 'failure' (before continue-on-error is applied)
    • steps.<id>.conclusion == 'success' (after continue-on-error is applied) [2]

continue-on-error at job level (jobs.<job_id>.continue-on-error)

  • Scope: The whole job. If the job fails, it does not fail the workflow run (“allow this job to fail without failing the workflow”). [1]
  • Matrix behavior / fail-fast interaction: It also affects whether other matrix jobs are canceled; with continue-on-error: true, other jobs in the matrix keep running even if this job fails. [1]

Practical “workflow fail” difference

  • Use step-level when you want the job to keep going past a risky step (but still be able to inspect that step’s outcome).
  • Use job-level when you want an entire job (often a specific matrix leg like “experimental”) to be allowed to fail while the overall workflow still passes. [1]

Sources: GitHub Actions workflow syntax docs (job/step continue-on-error) [1], GitHub Actions contexts docs (steps.<id>.outcome vs steps.<id>.conclusion) [2].


🏁 Script executed:

# List workflow files
git ls-files .github/workflows/ | head -20

Repository: game-ci/unity-builder

Length of output: 458


🏁 Script executed:

# Examine the macOS workflow file
cat -n .github/workflows/build-tests-mac.yml | head -30

Repository: game-ci/unity-builder

Length of output: 1057


🏁 Script executed:

# Check Ubuntu workflow for comparison
cat -n .github/workflows/build-tests-ubuntu.yml | sed -n '135,165p'

Repository: game-ci/unity-builder

Length of output: 1388


🏁 Script executed:

# Check Windows workflow for comparison
cat -n .github/workflows/build-tests-windows.yml | sed -n '70,105p'

Repository: game-ci/unity-builder

Length of output: 1607


Move continue-on-error from job level to step level.

At Line 15, continue-on-error: true is applied to the entire macOS job, allowing all matrix combinations to fail without failing the workflow. This diverges from Ubuntu and Windows, which apply continue-on-error at the step level (.github/workflows/build-tests-ubuntu.yml:139, .github/workflows/build-tests-windows.yml:75) using the same retry-on-failure pattern. Job-level tolerance prevents persistent failures from surfacing in CI; move this setting to the build step(s) instead to maintain consistent regression detection across all platforms.

Suggested change
 jobs:
   buildForAllPlatformsMacOS:
     name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
     runs-on: macos-latest
-    continue-on-error: true
     strategy:
       fail-fast: false
       matrix:
@@
       - uses: ./
+        id: build-1
+        continue-on-error: true
         env:
           UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
           UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
           UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
           UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-tests-mac.yml at line 15, Remove the job-level
continue-on-error: true (the top-level continue-on-error key applied to the
macOS job) and instead add continue-on-error: true to the specific build/test
step(s) that run the actual build and test commands (the same step(s) where the
retry-on-failure pattern is used in the Ubuntu/Windows workflows); keep the
matrix intact but ensure the job-level tolerance is removed so persistent
failures bubble up, and replicate the retry-on-failure step configuration from
the other platform workflows so only the targeted step(s) tolerate transient
failures.

The orchestrator-develop branch no longer exists. Update all fallback
clone commands and test fixtures to use main instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@frostebite

Copy link
Copy Markdown
Member Author

Closing — all orchestrator code has been extracted to the standalone game-ci/orchestrator repository.

Content from this PR (community plugin validation) is fully present in the orchestrator repo. See PR #819 for the extraction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Next-Gen Orchestrator Next-Gen experimental features orchestrator Orchestrator module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Community Plugin Validation — scheduled compile and build checks for Unity packages

1 participant