-
-
Notifications
You must be signed in to change notification settings - Fork 307
Next-Gen Features -- Combined Integration #814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
8d81236
feat(orchestrator): add test workflow engine placeholder
frostebite 49b37f7
feat(orchestrator): add hot runner protocol placeholder
frostebite b3e1639
feat(orchestrator): generic artifact system — output types, manifests…
frostebite 3033ee0
feat(orchestrator): incremental sync protocol — git delta, direct inp…
frostebite ccbe1bc
feat: community plugin validation workflow (#800)
frostebite 1bb31f3
feat(hot-runner): implement hot runner protocol with registry, health…
frostebite aa2e05d
feat(artifacts): complete generic artifact system with upload handler…
frostebite 1186717
feat(testing): implement test workflow engine with YAML suites, taxon…
frostebite 4870fb5
feat(sync): complete incremental sync protocol with storage-pull, sta…
frostebite 5e54bcd
fix(testing): use async exec for parallel test group execution
frostebite 7615bbd
fix(artifacts): validate rclone availability before storage upload
frostebite 7c0c4c2
fix(hot-runner): validate persisted registry state and add dispatcher…
frostebite 1e2bb88
style: fix prettier formatting
frostebite 5a42214
feat: add official game-ci CLI with build, activate, and orchestrate …
frostebite 5bdcf12
feat(cli): add npm publish workflow and CLI tests
frostebite 79d12aa
feat(cli): add release workflow, install scripts, and self-update com…
frostebite 280a10d
fix(cli): address review findings — exit codes, missing inputs, null …
frostebite f42930d
Merge remote-tracking branch 'origin/feature/test-workflow-engine' in…
frostebite 8d670d7
Merge remote-tracking branch 'origin/feature/hot-runner-protocol' int…
frostebite 708e6d7
Merge remote-tracking branch 'origin/feature/generic-artifact-system'…
frostebite 8b05655
Merge remote-tracking branch 'origin/feature/incremental-sync-protoco…
frostebite d81990c
Merge remote-tracking branch 'origin/feature/community-plugin-validat…
frostebite 9f0c5b3
Merge remote-tracking branch 'origin/feature/cli-support' into releas…
frostebite 4c91a33
chore: add integration branch update scripts for release/next-gen
frostebite db27f91
chore: add release/lts-infrastructure to update-all script
frostebite 676855f
ci: set macOS builds to continue-on-error
frostebite 78a7f6c
ci: mark failed macOS builds as neutral instead of failure
frostebite c0ca4b6
revert: restore build-tests-mac.yml to match main
frostebite b774d7f
fix(test): add gitAuthMode to orchestrator-folders test mock
frostebite 0633ca9
fix(ci): bump node version to 20 in integrity-check
frostebite bf25e1f
fix: downgrade yargs to ^17.7.2 for Node 18 compatibility
frostebite 4b44327
fix: replace orchestrator-develop branch references with main
frostebite d53ed6c
fix: remove stale merge conflict marker from action.yml
frostebite bc9332e
refactor(cli): move cache command under orchestrate subcommand
frostebite File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| name: Release CLI | ||
|
|
||
| on: | ||
| release: | ||
| types: [published] | ||
| workflow_dispatch: | ||
| inputs: | ||
| tag: | ||
| description: 'Release tag to build (e.g., v2.0.0). Uses latest release if empty.' | ||
| required: false | ||
| type: string | ||
| publish-npm: | ||
| description: 'Publish to npm' | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event.release.tag_name || inputs.tag || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build-binaries: | ||
| name: Build ${{ matrix.target }} | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - target: linux-x64 | ||
| os: ubuntu-latest | ||
| pkg-target: node20-linux-x64 | ||
| binary-name: game-ci-linux-x64 | ||
| - target: linux-arm64 | ||
| os: ubuntu-latest | ||
| pkg-target: node20-linux-arm64 | ||
| binary-name: game-ci-linux-arm64 | ||
| - target: macos-x64 | ||
| os: macos-latest | ||
| pkg-target: node20-macos-x64 | ||
| binary-name: game-ci-macos-x64 | ||
| - target: macos-arm64 | ||
| os: macos-latest | ||
| pkg-target: node20-macos-arm64 | ||
| binary-name: game-ci-macos-arm64 | ||
| - target: windows-x64 | ||
| os: windows-latest | ||
| pkg-target: node20-win-x64 | ||
| binary-name: game-ci-windows-x64.exe | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.release.tag_name || inputs.tag || github.ref }} | ||
|
|
||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install --frozen-lockfile | ||
|
|
||
| - name: Build TypeScript | ||
| run: yarn build | ||
|
|
||
| - name: Verify CLI before packaging | ||
| run: node lib/cli.js version | ||
|
|
||
| - name: Build standalone binary | ||
| run: npx pkg lib/cli.js --target ${{ matrix.pkg-target }} --output ${{ matrix.binary-name }} --compress GZip | ||
|
|
||
| - name: Verify standalone binary (non-cross-compiled) | ||
| if: | | ||
| (matrix.target == 'linux-x64' && runner.os == 'Linux') || | ||
| (matrix.target == 'macos-arm64' && runner.os == 'macOS' && runner.arch == 'ARM64') || | ||
| (matrix.target == 'macos-x64' && runner.os == 'macOS' && runner.arch == 'X64') || | ||
| (matrix.target == 'windows-x64' && runner.os == 'Windows') | ||
| run: ./${{ matrix.binary-name }} version | ||
| shell: bash | ||
|
|
||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: binary-${{ matrix.target }} | ||
| path: ${{ matrix.binary-name }} | ||
| retention-days: 5 | ||
|
|
||
| create-checksums-and-upload: | ||
| name: Checksums and release upload | ||
| needs: build-binaries | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| steps: | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| path: binaries | ||
| pattern: binary-* | ||
| merge-multiple: true | ||
|
|
||
| - name: List binaries | ||
| run: ls -la binaries/ | ||
|
|
||
| - name: Generate SHA256 checksums | ||
| run: | | ||
| cd binaries | ||
| sha256sum game-ci-* > checksums.txt | ||
| echo "=== checksums.txt ===" | ||
| cat checksums.txt | ||
|
|
||
| - name: Determine release tag | ||
| id: tag | ||
| run: | | ||
| if [ "${{ github.event_name }}" = "release" ]; then | ||
| echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" | ||
| elif [ -n "${{ inputs.tag }}" ]; then | ||
| echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "No release tag available. Skipping upload." | ||
| echo "tag=" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Upload binaries to release | ||
| if: steps.tag.outputs.tag != '' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| cd binaries | ||
| for f in game-ci-* checksums.txt; do | ||
| echo "Uploading $f..." | ||
| gh release upload "${{ steps.tag.outputs.tag }}" "$f" \ | ||
| --repo "${{ github.repository }}" \ | ||
| --clobber | ||
| done | ||
|
|
||
| publish-npm: | ||
| name: Publish to npm | ||
| needs: build-binaries | ||
| runs-on: ubuntu-latest | ||
| if: >- | ||
| (github.event_name == 'release') || (github.event_name == 'workflow_dispatch' && inputs.publish-npm) | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.release.tag_name || inputs.tag || github.ref }} | ||
|
|
||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| registry-url: 'https://registry.npmjs.org' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install --frozen-lockfile | ||
|
|
||
| - name: Build | ||
| run: yarn build | ||
|
|
||
| - name: Run tests | ||
| run: yarn test | ||
|
|
||
| - name: Verify CLI | ||
| run: | | ||
| node lib/cli.js version | ||
| node lib/cli.js --help | ||
|
|
||
| - name: Publish to npm | ||
| run: npm publish --provenance --access public | ||
| env: | ||
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| name: Validate Community Plugins | ||
|
|
||
| on: | ||
| schedule: | ||
| # Run weekly on Sunday at 02:00 UTC | ||
| - cron: '0 2 * * 0' | ||
| workflow_dispatch: | ||
| inputs: | ||
| plugin_filter: | ||
| description: 'Filter plugins by name (regex pattern, empty = all)' | ||
| required: false | ||
| default: '' | ||
| unity_version: | ||
| description: 'Override Unity version (empty = use plugin default)' | ||
| required: false | ||
| default: '' | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write | ||
|
|
||
| jobs: | ||
| load-plugins: | ||
| name: Load Plugin Registry | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.parse.outputs.matrix }} | ||
| plugin_count: ${{ steps.parse.outputs.count }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Parse plugin registry | ||
| id: parse | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const fs = require('fs'); | ||
| const yaml = require('js-yaml'); | ||
|
|
||
| const registry = yaml.load(fs.readFileSync('community-plugins.yml', 'utf8')); | ||
| let plugins = registry.plugins || []; | ||
|
|
||
| // Apply name filter if provided | ||
| const filter = '${{ github.event.inputs.plugin_filter }}'; | ||
| if (filter) { | ||
| const regex = new RegExp(filter, 'i'); | ||
| plugins = plugins.filter(p => regex.test(p.name)); | ||
| } | ||
|
|
||
| // Expand platform matrix | ||
| const matrix = []; | ||
| 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, | ||
| timeout: plugin.timeout || 30 | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| core.setOutput('matrix', JSON.stringify({ include: matrix })); | ||
| core.setOutput('count', matrix.length); | ||
| console.log(`Found ${matrix.length} plugin-platform combinations to validate`); | ||
|
|
||
| validate: | ||
| name: '${{ matrix.name }} (${{ matrix.platform }})' | ||
| needs: load-plugins | ||
| if: needs.load-plugins.outputs.plugin_count > 0 | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: ${{ fromJson(matrix.timeout) }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.load-plugins.outputs.matrix) }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Create test project | ||
| run: | | ||
| mkdir -p test-project/Assets | ||
| mkdir -p test-project/Packages | ||
| mkdir -p test-project/ProjectSettings | ||
|
|
||
| # Create minimal manifest.json | ||
| 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 | ||
|
|
||
| # Create minimal ProjectSettings | ||
| cat > test-project/ProjectSettings/ProjectVersion.txt << EOF | ||
| m_EditorVersion: ${{ matrix.unity }} | ||
| EOF | ||
|
|
||
| - name: Build with unity-builder | ||
| uses: ./ | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| id: build | ||
| with: | ||
| projectPath: test-project | ||
| targetPlatform: ${{ matrix.platform }} | ||
| unityVersion: ${{ matrix.unity }} | ||
| continue-on-error: true | ||
|
|
||
| - name: Record result | ||
| if: always() | ||
| run: | | ||
| STATUS="${{ steps.build.outcome }}" | ||
| echo "## ${{ matrix.name }} — ${{ matrix.platform }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| if [ "$STATUS" = "success" ]; then | ||
| echo "✅ **PASSED** — Compiled and built successfully" >> $GITHUB_STEP_SUMMARY | ||
| else | ||
| echo "❌ **FAILED** — Build or compilation failed" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Unity: ${{ matrix.unity }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Platform: ${{ matrix.platform }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Source: ${{ matrix.source }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Package: \`${{ matrix.package }}\`" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| report: | ||
| name: Validation Report | ||
| needs: [load-plugins, validate] | ||
| if: always() | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Generate summary | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const { data: run } = await github.rest.actions.listJobsForWorkflowRun({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| run_id: context.runId | ||
| }); | ||
|
|
||
| const validateJobs = run.jobs.filter(j => j.name.startsWith('validate')); | ||
| const passed = validateJobs.filter(j => j.conclusion === 'success').length; | ||
| const failed = validateJobs.filter(j => j.conclusion === 'failure').length; | ||
| const total = validateJobs.length; | ||
|
|
||
| let summary = `# Community Plugin Validation Report\n\n`; | ||
| summary += `**${passed}/${total} passed** | ${failed} failed\n\n`; | ||
| summary += `| Plugin | Platform | Status |\n|--------|----------|--------|\n`; | ||
|
|
||
| for (const job of validateJobs) { | ||
| const icon = job.conclusion === 'success' ? '✅' : '❌'; | ||
| summary += `| ${job.name} | | ${icon} ${job.conclusion} |\n`; | ||
| } | ||
|
|
||
| await core.summary.addRaw(summary).write(); | ||
|
|
||
| // Create or update issue if there are failures | ||
| if (failed > 0) { | ||
| const title = `Community Plugin Validation: ${failed} failure(s) — ${new Date().toISOString().split('T')[0]}`; | ||
| const body = summary + `\n\n[Workflow Run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`; | ||
|
|
||
| const { data: issues } = await github.rest.issues.listForRepo({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'open', | ||
| labels: 'community-plugin-validation' | ||
| }); | ||
|
|
||
| if (issues.length > 0) { | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: issues[0].number, | ||
| body: body | ||
| }); | ||
| } else { | ||
| await github.rest.issues.create({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| title: title, | ||
| body: body, | ||
| labels: ['community-plugin-validation'] | ||
| }); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Copilot Autofix
AI 16 days ago
In general, the fix is to explicitly define
permissions:for each job (or at the workflow root) to avoid relying on repository defaults. For thebuild-binariesjob, it only needs to read source code and use artifacts; it does not need to write to repository contents or perform other privileged operations. Therefore, we can safely grant itcontents: readas a minimal token permission.The best targeted fix is to add a
permissions:section under thebuild-binariesjob definition, right after theruns-on:or beforestrategy:. We’ll setcontents: readbecause the job checks out the repository and builds binaries but does not modify GitHub resources. Other jobs already have their own explicit permissions blocks and do not need changes.Concretely, in
.github/workflows/release-cli.yml, underjobs: build-binaries:, add:indented to align with other job-level keys. No imports or additional definitions are required, and this change does not affect existing functionality.