Compare commits

...

5 Commits

Author SHA1 Message Date
Frostebite
05a3792dc2 ci: run github check integration optionally 2025-08-03 20:03:22 +01:00
Frostebite
53e2b89833 test: add github check integration 2025-08-03 20:03:16 +01:00
Frostebite
d6dc078d5a test: always mock github check requests 2025-08-03 00:50:29 +01:00
Frostebite
b924651eb9 chore: format cloud runner github checks test 2025-08-02 20:15:17 +01:00
Frostebite
44586b3388 fix: mock github checks in tests 2025-08-02 19:38:47 +01:00
4 changed files with 125 additions and 41 deletions

View File

@@ -3,6 +3,11 @@ name: Cloud Runner CI Pipeline
on: on:
push: { branches: [cloud-runner-develop, cloud-runner-preview, main] } push: { branches: [cloud-runner-develop, cloud-runner-preview, main] }
workflow_dispatch: workflow_dispatch:
inputs:
runGithubIntegrationTests:
description: 'Run GitHub Checks integration tests'
required: false
default: 'false'
permissions: permissions:
checks: write checks: write
@@ -207,3 +212,20 @@ jobs:
name: ${{ matrix.providerStrategy }} Build (${{ matrix.targetPlatform }}) name: ${{ matrix.providerStrategy }} Build (${{ matrix.targetPlatform }})
path: ${{ steps.unity-build.outputs.BUILD_ARTIFACT }} path: ${{ steps.unity-build.outputs.BUILD_ARTIFACT }}
retention-days: 14 retention-days: 14
githubChecksIntegration:
name: GitHub Checks Integration
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && github.event.inputs.runGithubIntegrationTests == 'true'
env:
RUN_GITHUB_INTEGRATION_TESTS: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'
- run: yarn install --frozen-lockfile
- run: yarn test cloud-runner-github-checks.integration --detectOpenHandles --forceExit --runInBand
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,38 @@
import { BuildParameters } from '../model';
import CloudRunner from '../model/cloud-runner/cloud-runner';
import UnityVersioning from '../model/unity-versioning';
import { Cli } from '../model/cli/cli';
import GitHub from '../model/github';
import { OptionValues } from 'commander';
export const TIMEOUT_INFINITE = 1e9;
async function createParameters(overrides?: OptionValues) {
if (overrides) Cli.options = overrides;
return BuildParameters.create();
}
const runIntegration = process.env.RUN_GITHUB_INTEGRATION_TESTS === 'true';
const describeOrSkip = runIntegration ? describe : describe.skip;
describeOrSkip('Cloud Runner Github Checks Integration', () => {
it(
'creates and updates a real GitHub check',
async () => {
const buildParameter = await createParameters({
versioning: 'None',
projectPath: 'test-project',
unityVersion: UnityVersioning.read('test-project'),
asyncCloudRunner: `true`,
githubChecks: `true`,
});
await CloudRunner.setup(buildParameter);
const checkId = await GitHub.createGitHubCheck(`integration create`);
expect(checkId).not.toEqual('');
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `integration`);
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `integration`, `success`, `completed`);
},
TIMEOUT_INFINITE,
);
});

View File

@@ -1,5 +1,15 @@
import failOnConsole from 'jest-fail-on-console'; import failOnConsole from 'jest-fail-on-console';
// Polyfill fetch for the Node.js test environment.
// Jest runs tests inside a VM context where the global `fetch` is not
// automatically provided, even on Node 18+. Octokit requires a `fetch`
// implementation, so we provide one using undici's implementation.
// This ensures tests that interact with Octokit do not throw when
// constructing the client.
import { fetch as undiciFetch, Headers, Request, Response } from 'undici';
Object.assign(globalThis, { fetch: undiciFetch, Headers, Request, Response });
// Fail when console logs something inside a test - use spyOn instead // Fail when console logs something inside a test - use spyOn instead
failOnConsole({ failOnConsole({
shouldFailOnWarn: true, shouldFailOnWarn: true,

View File

@@ -2,7 +2,6 @@ import { BuildParameters } from '../..';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import UnityVersioning from '../../unity-versioning'; import UnityVersioning from '../../unity-versioning';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import CloudRunnerOptions from '../options/cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { OptionValues } from 'commander'; import { OptionValues } from 'commander';
import GitHub from '../../github'; import GitHub from '../../github';
@@ -16,44 +15,59 @@ describe('Cloud Runner Github Checks', () => {
setups(); setups();
it('Responds', () => {}); it('Responds', () => {});
if (CloudRunnerOptions.cloudRunnerDebug) { beforeEach(() => {
it( // Mock GitHub API requests to avoid real network calls
'Check Handling Direct', jest.spyOn(GitHub as any, 'createGitHubCheckRequest').mockResolvedValue({
async () => { status: 201,
// Setup parameters data: { id: '1' },
const buildParameter = await CreateParameters({ });
versioning: 'None', jest.spyOn(GitHub as any, 'updateGitHubCheckRequest').mockResolvedValue({
projectPath: 'test-project', status: 200,
unityVersion: UnityVersioning.read('test-project'), data: {},
asyncCloudRunner: `true`, });
githubChecks: `true`, jest.spyOn(GitHub as any, 'runUpdateAsyncChecksWorkflow').mockResolvedValue(undefined);
}); });
await CloudRunner.setup(buildParameter);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`); afterEach(() => {
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`); jest.restoreAllMocks();
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`); });
},
TIMEOUT_INFINITE, it(
); 'Check Handling Direct',
it( async () => {
'Check Handling Via Async Workflow', // Setup parameters
async () => { const buildParameter = await CreateParameters({
// Setup parameters versioning: 'None',
const buildParameter = await CreateParameters({ projectPath: 'test-project',
versioning: 'None', unityVersion: UnityVersioning.read('test-project'),
projectPath: 'test-project', asyncCloudRunner: `true`,
unityVersion: UnityVersioning.read('test-project'), githubChecks: `true`,
asyncCloudRunner: `true`, });
githubChecks: `true`, await CloudRunner.setup(buildParameter);
}); CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`);
GitHub.forceAsyncTest = true; await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`);
await CloudRunner.setup(buildParameter); await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`); },
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`); TIMEOUT_INFINITE,
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`); );
GitHub.forceAsyncTest = false; it(
}, 'Check Handling Via Async Workflow',
TIMEOUT_INFINITE, async () => {
); // Setup parameters
} const buildParameter = await CreateParameters({
versioning: 'None',
projectPath: 'test-project',
unityVersion: UnityVersioning.read('test-project'),
asyncCloudRunner: `true`,
githubChecks: `true`,
});
GitHub.forceAsyncTest = true;
await CloudRunner.setup(buildParameter);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`);
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`);
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`);
GitHub.forceAsyncTest = false;
},
TIMEOUT_INFINITE,
);
}); });