Revert "triggerWorkflowOnComplete param for cloud runner"

This reverts commit 00c5685d03.
This commit is contained in:
Frostebite 2023-02-05 00:22:32 +00:00
parent 00c5685d03
commit 28147e5e1b
21 changed files with 87 additions and 242 deletions

View File

@ -39,21 +39,20 @@ jobs:
if: github.event.event_type != 'pull_request_target' if: github.event.event_type != 'pull_request_target'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- timeout-minutes: 180 - name: Checkout (default)
uses: actions/checkout@v2
with:
lfs: false
- run: yarn
- run: yarn run cli -m checks-update
timeout-minutes: 180
env: env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
PROJECT_PATH: test-project PROJECT_PATH: test-project
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_PRIVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_PLATFORM: StandaloneWindows64 TARGET_PLATFORM: StandaloneWindows64
cloudRunnerTests: true cloudRunnerTests: true
versioning: None versioning: None
CLOUD_RUNNER_CLUSTER: local-docker CLOUD_RUNNER_CLUSTER: local-docker
AWS_BASE_STACK_NAME: game-ci-github-pipelines AWS_BASE_STACK_NAME: game-ci-github-pipelines
CHECKS_UPDATE: ${{ github.event.inputs.checksObject }} CHECKS_UPDATE: ${{ github.event.inputs.checksObject }}
run: |
git clone -b cloud-runner-develop https://github.com/game-ci/unity-builder
cd unity-builder
yarn
ls
yarn run cli -m checks-update

View File

@ -31,8 +31,6 @@ env:
UNITY_VERSION: 2019.3.15f1 UNITY_VERSION: 2019.3.15f1
USE_IL2CPP: false USE_IL2CPP: false
USE_GKE_GCLOUD_AUTH_PLUGIN: true USE_GKE_GCLOUD_AUTH_PLUGIN: true
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs: jobs:
integrationTests: integrationTests:
@ -51,31 +49,42 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
lfs: false lfs: false
- uses: google-github-actions/auth@v1
with:
credentials_json: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Get GKE cluster credentials
run: |
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
gcloud components install gke-gcloud-auth-plugin
gcloud container clusters get-credentials $GKE_CLUSTER --zone $GKE_ZONE --project $GKE_PROJECT
- name: Configure AWS Credentials - name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1 uses: aws-actions/configure-aws-credentials@v1
with: with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2 aws-region: eu-west-2
- uses: google-github-actions/auth@v1
if: matrix.CloudRunnerCluster == 'k8s'
with:
credentials_json: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }}
- name: 'Set up Cloud SDK'
if: matrix.CloudRunnerCluster == 'k8s'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Get GKE cluster credentials
if: matrix.CloudRunnerCluster == 'k8s'
run: |
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
gcloud components install gke-gcloud-auth-plugin
gcloud container clusters get-credentials $GKE_CLUSTER --zone $GKE_ZONE --project $GKE_PROJECT
- run: yarn - run: yarn
- run: yarn run test-i --detectOpenHandles --forceExit --runInBand - run: yarn run test "cloud-runner-async-workflow" --detectOpenHandles --forceExit --runInBand
if: matrix.CloudRunnerCluster != 'local-docker'
timeout-minutes: 180 timeout-minutes: 180
env: env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
PROJECT_PATH: test-project PROJECT_PATH: test-project
GIT_PRIVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_PLATFORM: StandaloneWindows64
cloudRunnerTests: true
versioning: None
CLOUD_RUNNER_CLUSTER: ${{ matrix.cloudRunnerCluster }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: yarn run test-i --detectOpenHandles --forceExit --runInBand
if: matrix.CloudRunnerCluster == 'local-docker'
timeout-minutes: 180
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
PROJECT_PATH: test-project
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_PLATFORM: StandaloneWindows64 TARGET_PLATFORM: StandaloneWindows64
cloudRunnerTests: true cloudRunnerTests: true
versioning: None versioning: None
@ -105,12 +114,14 @@ jobs:
- run: yarn - run: yarn
- uses: ./ - uses: ./
id: unity-build id: unity-build
timeout-minutes: 30 timeout-minutes: 90
env: env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with: with:
cloudRunnerTests: true cloudRunnerTests: true
versioning: None versioning: None
projectPath: test-project
gitPrivateToken: ${{ secrets.GITHUB_TOKEN }}
targetPlatform: ${{ matrix.targetPlatform }} targetPlatform: ${{ matrix.targetPlatform }}
cloudRunnerCluster: ${{ matrix.cloudRunnerCluster }} cloudRunnerCluster: ${{ matrix.cloudRunnerCluster }}
- run: | - run: |

BIN
dist/exec-child.js vendored

Binary file not shown.

BIN
dist/index.js generated vendored

Binary file not shown.

BIN
dist/index.js.map generated vendored

Binary file not shown.

BIN
dist/licenses.txt generated vendored

Binary file not shown.

BIN
dist/sourcemap-register.js generated vendored

Binary file not shown.

Binary file not shown.

View File

@ -71,9 +71,6 @@ class BuildParameters {
public garbageCollectionMaxAge!: number; public garbageCollectionMaxAge!: number;
public constantGarbageCollection!: boolean; public constantGarbageCollection!: boolean;
public githubChecks!: boolean; public githubChecks!: boolean;
public asyncWorkflow!: boolean;
public githubCheckId!: string;
public triggerWorkflowOnComplete!: string[];
static async create(): Promise<BuildParameters> { static async create(): Promise<BuildParameters> {
const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle); const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle);
@ -158,9 +155,6 @@ class BuildParameters {
constantGarbageCollection: CloudRunnerOptions.constantGarbageCollection, constantGarbageCollection: CloudRunnerOptions.constantGarbageCollection,
garbageCollectionMaxAge: CloudRunnerOptions.garbageCollectionMaxAge, garbageCollectionMaxAge: CloudRunnerOptions.garbageCollectionMaxAge,
githubChecks: CloudRunnerOptions.githubChecks, githubChecks: CloudRunnerOptions.githubChecks,
asyncWorkflow: CloudRunnerOptions.asyncCloudRunner,
githubCheckId: CloudRunnerOptions.githubCheckId,
triggerWorkflowOnComplete: CloudRunnerOptions.triggerWorkflowOnComplete,
}; };
} }

View File

@ -56,7 +56,7 @@ export class Cli {
program.parse(process.argv); program.parse(process.argv);
Cli.options = program.opts(); Cli.options = program.opts();
return Cli.isCliMode || process.env.GAMECI_CLI; return Cli.isCliMode;
} }
static async RunCli(): Promise<void> { static async RunCli(): Promise<void> {
@ -113,16 +113,12 @@ export class Cli {
public static async asyncronousWorkflow(): Promise<string> { public static async asyncronousWorkflow(): Promise<string> {
const buildParameter = await BuildParameters.create(); const buildParameter = await BuildParameters.create();
const baseImage = new ImageTag(buildParameter); const baseImage = new ImageTag(buildParameter);
await CloudRunner.setup(buildParameter);
return await CloudRunner.run(buildParameter, baseImage.toString()); return await CloudRunner.run(buildParameter, baseImage.toString());
} }
@CliFunction(`checks-update`, `runs a cloud runner build`) @CliFunction(`checks-update`, `runs a cloud runner build`)
public static async checksUpdate() { public static async checksUpdate() {
const buildParameter = await BuildParameters.create();
await CloudRunner.setup(buildParameter);
const input = JSON.parse(process.env.CHECKS_UPDATE || ``); const input = JSON.parse(process.env.CHECKS_UPDATE || ``);
core.info(`Checks Update ${process.env.CHECKS_UPDATE}`); core.info(`Checks Update ${process.env.CHECKS_UPDATE}`);
if (input.mode === `create`) { if (input.mode === `create`) {

View File

@ -62,9 +62,6 @@ class CloudRunnerOptions {
static get githubChecks(): boolean { static get githubChecks(): boolean {
return CloudRunnerOptions.getInput('githubChecks') || false; return CloudRunnerOptions.getInput('githubChecks') || false;
} }
static get githubCheckId(): string {
return CloudRunnerOptions.getInput('githubCheckId') || ``;
}
static get githubOwner() { static get githubOwner() {
return CloudRunnerOptions.getInput('githubOwner') || CloudRunnerOptions.githubRepo.split(`/`)[0] || false; return CloudRunnerOptions.getInput('githubOwner') || CloudRunnerOptions.githubRepo.split(`/`)[0] || false;
@ -74,10 +71,6 @@ class CloudRunnerOptions {
return CloudRunnerOptions.getInput('githubRepoName') || CloudRunnerOptions.githubRepo.split(`/`)[1] || false; return CloudRunnerOptions.getInput('githubRepoName') || CloudRunnerOptions.githubRepo.split(`/`)[1] || false;
} }
static get triggerWorkflowOnComplete() {
return CloudRunnerOptions.getInput('triggerWorkflowOnComplete')?.split(',') || [];
}
// ### ### ### // ### ### ###
// Git syncronization parameters // Git syncronization parameters
// ### ### ### // ### ### ###
@ -249,7 +242,7 @@ class CloudRunnerOptions {
return CloudRunnerOptions.getInput(`watchToEnd`) || true; return CloudRunnerOptions.getInput(`watchToEnd`) || true;
} }
public static get asyncCloudRunner(): boolean { static get asyncCloudRunner(): boolean {
return (CloudRunnerOptions.getInput('asyncCloudRunner') || `false`) === `true` || false; return (CloudRunnerOptions.getInput('asyncCloudRunner') || `false`) === `true` || false;
} }
@ -258,7 +251,7 @@ class CloudRunnerOptions {
} }
public static get useSharedBuilder(): boolean { public static get useSharedBuilder(): boolean {
return (CloudRunnerOptions.getInput(`useSharedBuilder`) || 'false') === 'true'; return (CloudRunnerOptions.getInput(`useSharedBuilder`) || 'true') === 'true';
} }
public static get useLz4Compression(): boolean { public static get useLz4Compression(): boolean {

View File

@ -23,19 +23,11 @@ class CloudRunner {
private static cloudRunnerEnvironmentVariables: CloudRunnerEnvironmentVariable[]; private static cloudRunnerEnvironmentVariables: CloudRunnerEnvironmentVariable[];
static lockedWorkspace: string | undefined; static lockedWorkspace: string | undefined;
public static readonly retainedWorkspacePrefix: string = `retained-workspace`; public static readonly retainedWorkspacePrefix: string = `retained-workspace`;
public static get isCloudRunnerEnvironment() { public static githubCheckId;
return process.env[`GITHUB_ACTIONS`] !== `true`; public static setup(buildParameters: BuildParameters) {
}
public static get isCloudRunnerAsyncEnvironment() {
return process.env[`GAMECI_ASYNC_WORKFLOW`] === `true`;
}
public static async setup(buildParameters: BuildParameters) {
CloudRunnerLogger.setup(); CloudRunnerLogger.setup();
CloudRunnerLogger.log(`Setting up cloud runner`); CloudRunnerLogger.log(`Setting up cloud runner`);
CloudRunner.buildParameters = buildParameters; CloudRunner.buildParameters = buildParameters;
if (CloudRunner.buildParameters.githubCheckId === ``) {
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(CloudRunner.buildParameters.buildGuid);
}
CloudRunner.setupSelectedBuildPlatform(); CloudRunner.setupSelectedBuildPlatform();
CloudRunner.defaultSecrets = TaskParameterSerializer.readDefaultSecrets(); CloudRunner.defaultSecrets = TaskParameterSerializer.readDefaultSecrets();
CloudRunner.cloudRunnerEnvironmentVariables = CloudRunner.cloudRunnerEnvironmentVariables =
@ -81,8 +73,10 @@ class CloudRunner {
} }
static async run(buildParameters: BuildParameters, baseImage: string) { static async run(buildParameters: BuildParameters, baseImage: string) {
await CloudRunner.setup(buildParameters); CloudRunner.setup(buildParameters);
try { try {
CloudRunner.githubCheckId = await GitHub.createGitHubCheck(CloudRunner.buildParameters.buildGuid);
if (buildParameters.retainWorkspace) { if (buildParameters.retainWorkspace) {
CloudRunner.lockedWorkspace = `${CloudRunner.retainedWorkspacePrefix}-${CloudRunner.buildParameters.buildGuid}`; CloudRunner.lockedWorkspace = `${CloudRunner.retainedWorkspacePrefix}-${CloudRunner.buildParameters.buildGuid}`;
@ -112,11 +106,7 @@ class CloudRunner {
CloudRunner.defaultSecrets, CloudRunner.defaultSecrets,
); );
if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); if (!CloudRunner.buildParameters.isCliMode) core.endGroup();
const content = { ...CloudRunner.buildParameters }; await GitHub.updateGitHubCheck(CloudRunner.buildParameters.buildGuid, CloudRunner.buildParameters.buildGuid);
content.gitPrivateToken = ``;
content.unitySerial = ``;
const jsonContent = JSON.stringify(content, undefined, 4);
await GitHub.updateGitHubCheck(jsonContent, CloudRunner.buildParameters.buildGuid);
const output = await new WorkflowCompositionRoot().run( const output = await new WorkflowCompositionRoot().run(
new CloudRunnerStepState(baseImage, CloudRunner.cloudRunnerEnvironmentVariables, CloudRunner.defaultSecrets), new CloudRunnerStepState(baseImage, CloudRunner.cloudRunnerEnvironmentVariables, CloudRunner.defaultSecrets),
); );
@ -140,8 +130,6 @@ class CloudRunner {
CloudRunner.lockedWorkspace = undefined; CloudRunner.lockedWorkspace = undefined;
} }
await GitHub.triggerWorkflowOnComplete(CloudRunner.buildParameters.triggerWorkflowOnComplete);
if (buildParameters.constantGarbageCollection) { if (buildParameters.constantGarbageCollection) {
CloudRunner.Provider.garbageCollect(``, true, buildParameters.garbageCollectionMaxAge, true, true); CloudRunner.Provider.garbageCollect(``, true, buildParameters.garbageCollectionMaxAge, true, true);
} }

View File

@ -77,9 +77,6 @@ class AWSTaskRunner {
const containerState = taskData.containers?.[0]; const containerState = taskData.containers?.[0];
const exitCode = containerState?.exitCode || undefined; const exitCode = containerState?.exitCode || undefined;
CloudRunnerLogger.log(`Container State: ${JSON.stringify(containerState, undefined, 4)}`); CloudRunnerLogger.log(`Container State: ${JSON.stringify(containerState, undefined, 4)}`);
if (exitCode === undefined) {
CloudRunnerLogger.logWarning(`No exitcode for container`);
}
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING'); const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) { if (wasSuccessful) {
CloudRunnerLogger.log(`Cloud runner job has finished successfully`); CloudRunnerLogger.log(`Cloud runner job has finished successfully`);

View File

@ -129,27 +129,14 @@ class Kubernetes implements ProviderInterface {
this.jobName = `unity-builder-job-${this.buildGuid}`; this.jobName = `unity-builder-job-${this.buildGuid}`;
this.containerName = `main`; this.containerName = `main`;
await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient); await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
await this.createNamespacedJob(commands, image, mountdir, workingdir, environment, secrets);
this.setPodNameAndContainerName(await Kubernetes.findPodFromJob(this.kubeClient, this.jobName, this.namespace));
CloudRunnerLogger.log('Watching pod until running');
await KubernetesTaskRunner.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
let output = ''; let output = '';
// eslint-disable-next-line no-constant-condition // eslint-disable-next-line no-constant-condition
while (true) { while (true) {
try { try {
let existsAlready = false;
let status;
try {
status = await this.kubeClient.readNamespacedPodStatus(this.podName, this.namespace);
CloudRunnerLogger.log(JSON.stringify(status.body.status?.containerStatuses, undefined, 4));
existsAlready = true;
} catch {
// empty
}
if (!existsAlready || status.state?.terminated !== undefined) {
CloudRunnerLogger.log('Job does not exist');
await this.createNamespacedJob(commands, image, mountdir, workingdir, environment, secrets);
const find = await Kubernetes.findPodFromJob(this.kubeClient, this.jobName, this.namespace);
this.setPodNameAndContainerName(find);
CloudRunnerLogger.log('Watching pod until running');
await KubernetesTaskRunner.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
}
CloudRunnerLogger.log('Pod running, streaming logs'); CloudRunnerLogger.log('Pod running, streaming logs');
output = await KubernetesTaskRunner.runTask( output = await KubernetesTaskRunner.runTask(
this.kubeConfig, this.kubeConfig,
@ -176,12 +163,11 @@ class Kubernetes implements ProviderInterface {
errorParsed = error; errorParsed = error;
} }
const errorMessage = const reason = errorParsed.reason || errorParsed.response?.body?.reason || ``;
errorParsed.name || errorParsed.reason || errorParsed.response?.body?.reason || errorParsed.message; const errorMessage = errorParsed.message || reason;
const continueStreaming = const continueStreaming =
errorMessage.includes(`dial timeout, backstop`) || errorMessage.includes(`dial timeout, backstop`) ||
errorMessage.includes(`HttpError`) ||
errorMessage.includes(`HttpError: HTTP request failed`) || errorMessage.includes(`HttpError: HTTP request failed`) ||
errorMessage.includes(`an error occurred when try to find container`) || errorMessage.includes(`an error occurred when try to find container`) ||
errorMessage.includes(`not found`) || errorMessage.includes(`not found`) ||
@ -206,18 +192,6 @@ class Kubernetes implements ProviderInterface {
} }
} }
private async doesJobExist(name) {
const jobs = await this.kubeClientBatch.listNamespacedJob(this.namespace);
return jobs.body.items.some((x) => x.metadata?.name === name);
}
private async doesFailedJobExist() {
const podStatus = await this.kubeClient.readNamespacedPodStatus(this.podName, this.namespace);
return podStatus.body.status?.phase === `Failed`;
}
private async createNamespacedJob( private async createNamespacedJob(
commands: string, commands: string,
image: string, image: string,
@ -243,12 +217,12 @@ class Kubernetes implements ProviderInterface {
k8s, k8s,
); );
await new Promise((promise) => setTimeout(promise, 15000)); await new Promise((promise) => setTimeout(promise, 15000));
const result = await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec); await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
CloudRunnerLogger.log(`Build job created`); CloudRunnerLogger.log(`Build job created`);
await new Promise((promise) => setTimeout(promise, 5000)); await new Promise((promise) => setTimeout(promise, 5000));
CloudRunnerLogger.log('Job created'); CloudRunnerLogger.log('Job created');
return result.body.metadata?.name; return;
} catch (error) { } catch (error) {
CloudRunnerLogger.log(`Error occured creating job: ${error}`); CloudRunnerLogger.log(`Error occured creating job: ${error}`);
throw error; throw error;

View File

@ -7,7 +7,6 @@ import waitUntil from 'async-wait-until';
import { FollowLogStreamService } from '../../services/follow-log-stream-service'; import { FollowLogStreamService } from '../../services/follow-log-stream-service';
class KubernetesTaskRunner { class KubernetesTaskRunner {
static lastReceivedTimestamp: number;
static async runTask( static async runTask(
kubeConfig: KubeConfig, kubeConfig: KubeConfig,
kubeClient: CoreV1Api, kubeClient: CoreV1Api,
@ -34,51 +33,15 @@ class KubernetesTaskRunner {
)); ));
next(); next();
}; };
// export interface LogOptions {
/**
* Follow the log stream of the pod. Defaults to false.
*/
// follow?: boolean;
/**
* If set, the number of bytes to read from the server before terminating the log output. This may not display a
* complete final line of logging, and may return slightly more or slightly less than the specified limit.
*/
// limitBytes?: number;
/**
* If true, then the output is pretty printed.
*/
// pretty?: boolean;
/**
* Return previous terminated container logs. Defaults to false.
*/
// previous?: boolean;
/**
* A relative time in seconds before the current time from which to show logs. If this value precedes the time a
* pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will
* be returned. Only one of sinceSeconds or sinceTime may be specified.
*/
// sinceSeconds?: number;
/**
* If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation
* of the container or sinceSeconds or sinceTime
*/
// tailLines?: number;
/**
* If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line of log output. Defaults to false.
*/
// timestamps?: boolean;
// }
const logOptions = { const logOptions = {
follow: true, follow: true,
pretty: false, pretty: false,
previous: true, previous: false,
timestamps: true,
sinceSeconds: KubernetesTaskRunner.lastReceivedTimestamp,
}; };
try { try {
const resultError = await new Log(kubeConfig).log(namespace, podName, containerName, stream, logOptions); const resultError = await new Promise((resolve) =>
new Log(kubeConfig).log(namespace, podName, containerName, stream, resolve, logOptions),
);
stream.destroy(); stream.destroy();
if (resultError) { if (resultError) {
throw resultError; throw resultError;
@ -110,8 +73,6 @@ class KubernetesTaskRunner {
if (stream) { if (stream) {
stream.destroy(); stream.destroy();
} }
CloudRunnerLogger.log(JSON.stringify(error));
CloudRunnerLogger.log('k8s task runner failed');
throw error; throw error;
} }
CloudRunnerLogger.log('end of log stream'); CloudRunnerLogger.log('end of log stream');

View File

@ -10,7 +10,6 @@ import CloudRunnerLogger from '../services/cloud-runner-logger';
import { CliFunction } from '../../cli/cli-functions-repository'; import { CliFunction } from '../../cli/cli-functions-repository';
import { CloudRunnerSystem } from '../services/cloud-runner-system'; import { CloudRunnerSystem } from '../services/cloud-runner-system';
import YAML from 'yaml'; import YAML from 'yaml';
import GitHub from '../../github';
export class RemoteClient { export class RemoteClient {
public static async bootstrapRepository() { public static async bootstrapRepository() {
@ -21,7 +20,7 @@ export class RemoteClient {
); );
process.chdir(CloudRunnerFolders.ToLinuxFolder(CloudRunnerFolders.repoPathAbsolute)); process.chdir(CloudRunnerFolders.ToLinuxFolder(CloudRunnerFolders.repoPathAbsolute));
await RemoteClient.cloneRepoWithoutLFSFiles(); await RemoteClient.cloneRepoWithoutLFSFiles();
await RemoteClient.replaceLargePackageReferencesWithSharedReferences(); RemoteClient.replaceLargePackageReferencesWithSharedReferences();
await RemoteClient.sizeOfFolder( await RemoteClient.sizeOfFolder(
'repo before lfs cache pull', 'repo before lfs cache pull',
CloudRunnerFolders.ToLinuxFolder(CloudRunnerFolders.repoPathAbsolute), CloudRunnerFolders.ToLinuxFolder(CloudRunnerFolders.repoPathAbsolute),
@ -96,12 +95,7 @@ export class RemoteClient {
assert(fs.existsSync(`.git`), 'git folder exists'); assert(fs.existsSync(`.git`), 'git folder exists');
RemoteClientLogger.log(`${CloudRunner.buildParameters.branch}`); RemoteClientLogger.log(`${CloudRunner.buildParameters.branch}`);
await CloudRunnerSystem.Run(`git checkout ${CloudRunner.buildParameters.branch}`); await CloudRunnerSystem.Run(`git checkout ${CloudRunner.buildParameters.branch}`);
if (CloudRunner.buildParameters.gitSha !== undefined) { await CloudRunnerSystem.Run(`git checkout ${CloudRunner.buildParameters.gitSha}`);
await CloudRunnerSystem.Run(`git checkout ${CloudRunner.buildParameters.gitSha}`);
} else {
RemoteClientLogger.log(`buildParameter Git Sha is empty`);
}
assert(fs.existsSync(path.join(`.git`, `lfs`)), 'LFS folder should not exist before caching'); assert(fs.existsSync(path.join(`.git`, `lfs`)), 'LFS folder should not exist before caching');
RemoteClientLogger.log(`Checked out ${CloudRunner.buildParameters.branch}`); RemoteClientLogger.log(`Checked out ${CloudRunner.buildParameters.branch}`);
} catch (error) { } catch (error) {
@ -110,17 +104,16 @@ export class RemoteClient {
} }
} }
static async replaceLargePackageReferencesWithSharedReferences() { static replaceLargePackageReferencesWithSharedReferences() {
CloudRunnerLogger.log(`Use Shared Pkgs ${CloudRunner.buildParameters.useSharedLargePackages}`);
GitHub.updateGitHubCheck(`Use Shared Pkgs ${CloudRunner.buildParameters.useSharedLargePackages}`, ``);
if (CloudRunner.buildParameters.useSharedLargePackages) { if (CloudRunner.buildParameters.useSharedLargePackages) {
await CloudRunnerSystem.Run(`tree -L 2 ${CloudRunnerFolders.projectPathAbsolute}`);
const filePath = path.join(CloudRunnerFolders.projectPathAbsolute, `Packages/manifest.json`); const filePath = path.join(CloudRunnerFolders.projectPathAbsolute, `Packages/manifest.json`);
let manifest = fs.readFileSync(filePath, 'utf8'); let manifest = fs.readFileSync(filePath, 'utf8');
manifest = manifest.replace(/LargeContent/g, '../../../LargeContent'); manifest = manifest.replace(/LargeContent/g, '../../../LargeContent');
fs.writeFileSync(filePath, manifest); fs.writeFileSync(filePath, manifest);
CloudRunnerLogger.log(`Package Manifest \n ${manifest}`); if (CloudRunner.buildParameters.cloudRunnerDebug) {
GitHub.updateGitHubCheck(`Package Manifest \n ${manifest}`, ``); CloudRunnerLogger.log(`Package Manifest`);
CloudRunnerLogger.log(manifest);
}
} }
} }
@ -163,6 +156,6 @@ export class RemoteClient {
if (!CloudRunner.buildParameters.retainWorkspace) { if (!CloudRunner.buildParameters.retainWorkspace) {
return; return;
} }
RemoteClientLogger.log(`Retained Workspace: ${CloudRunner.lockedWorkspace !== undefined}`); RemoteClientLogger.log(`Retained Workspace: ${CloudRunner.lockedWorkspace}`);
} }
} }

View File

@ -5,7 +5,6 @@ import { CloudRunnerStatics } from '../cloud-runner-statics';
import GitHub from '../../github'; import GitHub from '../../github';
export class FollowLogStreamService { export class FollowLogStreamService {
static errors = ``;
public static handleIteration(message, shouldReadLogs, shouldCleanup, output) { public static handleIteration(message, shouldReadLogs, shouldCleanup, output) {
if (message.includes(`---${CloudRunner.buildParameters.logId}`)) { if (message.includes(`---${CloudRunner.buildParameters.logId}`)) {
CloudRunnerLogger.log('End of log transmission received'); CloudRunnerLogger.log('End of log transmission received');
@ -18,27 +17,10 @@ export class FollowLogStreamService {
GitHub.updateGitHubCheck(`Build succeeded`, `Build succeeded`); GitHub.updateGitHubCheck(`Build succeeded`, `Build succeeded`);
core.setOutput('build-result', 'success'); core.setOutput('build-result', 'success');
} else if (message.includes('Build fail')) { } else if (message.includes('Build fail')) {
GitHub.updateGitHubCheck( GitHub.updateGitHubCheck(`Build failed`, `Build failed`);
`Build failed\n${FollowLogStreamService.errors}`,
`Build failed`,
`failure`,
`completed`,
);
core.setOutput('build-result', 'failed'); core.setOutput('build-result', 'failed');
core.setFailed('unity build failed'); core.setFailed('unity build failed');
core.error('BUILD FAILED!'); core.error('BUILD FAILED!');
} else if (message.toLowerCase().includes('error ')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (message.toLowerCase().includes('command failed: ')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (message.toLowerCase().includes('error: ')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (message.toLowerCase().includes('invalid ')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (message.toLowerCase().includes('incompatible ')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (message.toLowerCase().includes('cannot be found')) {
FollowLogStreamService.errors += `\n${message}`;
} else if (CloudRunner.buildParameters.cloudRunnerDebug && message.includes(': Listening for Jobs')) { } else if (CloudRunner.buildParameters.cloudRunnerDebug && message.includes(': Listening for Jobs')) {
core.setOutput('cloud runner stop watching', 'true'); core.setOutput('cloud runner stop watching', 'true');
shouldReadLogs = false; shouldReadLogs = false;

View File

@ -11,9 +11,6 @@ export class AsyncWorkflow {
): Promise<string> { ): Promise<string> {
try { try {
CloudRunnerLogger.log(`Cloud Runner is running async mode`); CloudRunnerLogger.log(`Cloud Runner is running async mode`);
const asyncEnvironmentVariable = new CloudRunnerEnvironmentVariable();
asyncEnvironmentVariable.name = `GAMECI_ASYNC_WORKFLOW`;
asyncEnvironmentVariable.value = `true`;
let output = ''; let output = '';
@ -37,7 +34,7 @@ aws --version
node /builder/dist/index.js -m async-workflow`, node /builder/dist/index.js -m async-workflow`,
`/${CloudRunnerFolders.buildVolumeFolder}`, `/${CloudRunnerFolders.buildVolumeFolder}`,
`/${CloudRunnerFolders.buildVolumeFolder}/`, `/${CloudRunnerFolders.buildVolumeFolder}/`,
[...environmentVariables, asyncEnvironmentVariable], environmentVariables,
[ [
...secrets, ...secrets,
...[ ...[

View File

@ -9,11 +9,7 @@ import { AsyncWorkflow } from './async-workflow';
export class WorkflowCompositionRoot implements WorkflowInterface { export class WorkflowCompositionRoot implements WorkflowInterface {
async run(cloudRunnerStepState: CloudRunnerStepState) { async run(cloudRunnerStepState: CloudRunnerStepState) {
try { try {
if ( if (CloudRunnerOptions.asyncCloudRunner) {
CloudRunnerOptions.asyncCloudRunner &&
!CloudRunner.isCloudRunnerAsyncEnvironment &&
!CloudRunner.isCloudRunnerEnvironment
) {
return await AsyncWorkflow.runAsyncWorkflow(cloudRunnerStepState.environment, cloudRunnerStepState.secrets); return await AsyncWorkflow.runAsyncWorkflow(cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
} }

View File

@ -9,7 +9,6 @@ class GitHub {
private static longDescriptionContent: string = ``; private static longDescriptionContent: string = ``;
private static startedDate: string; private static startedDate: string;
private static endedDate: string; private static endedDate: string;
static result: string = ``;
private static get octokitDefaultToken() { private static get octokitDefaultToken() {
return new Octokit({ return new Octokit({
auth: process.env.GITHUB_TOKEN, auth: process.env.GITHUB_TOKEN,
@ -33,7 +32,7 @@ class GitHub {
} }
private static get checkRunId() { private static get checkRunId() {
return CloudRunner.buildParameters.githubCheckId; return CloudRunner.githubCheckId;
} }
private static get owner() { private static get owner() {
@ -45,12 +44,13 @@ class GitHub {
} }
public static async createGitHubCheck(summary) { public static async createGitHubCheck(summary) {
if (!CloudRunnerOptions.githubChecks || CloudRunner.isCloudRunnerEnvironment) { if (!CloudRunnerOptions.githubChecks) {
return ``; return ``;
} }
GitHub.startedDate = new Date().toISOString(); GitHub.startedDate = new Date().toISOString();
CloudRunnerLogger.log(`Creating inital github check`); CloudRunnerLogger.log(`POST /repos/${GitHub.owner}/${GitHub.repo}/check-runs`);
const data = { const data = {
owner: GitHub.owner, owner: GitHub.owner,
repo: GitHub.repo, repo: GitHub.repo,
@ -77,20 +77,15 @@ class GitHub {
}; };
const result = await GitHub.createGitHubCheckRequest(data); const result = await GitHub.createGitHubCheckRequest(data);
return result.data.id.toString(); return result.data.id;
} }
public static async updateGitHubCheck(longDescription, summary, result = `neutral`, status = `in_progress`) { public static async updateGitHubCheck(longDescription, summary, result = `neutral`, status = `in_progress`) {
const isLocalAsync = CloudRunner.buildParameters.asyncWorkflow && !CloudRunner.isCloudRunnerAsyncEnvironment; if (!CloudRunnerOptions.githubChecks) {
if (!CloudRunnerOptions.githubChecks || isLocalAsync) {
return; return;
} }
GitHub.longDescriptionContent += `\n${longDescription}`; GitHub.longDescriptionContent += `\n${longDescription}`;
if (GitHub.result !== `success` && GitHub.result !== `failure`) {
GitHub.result = result;
} else {
result = GitHub.result;
}
const data: any = { const data: any = {
owner: GitHub.owner, owner: GitHub.owner,
repo: GitHub.repo, repo: GitHub.repo,
@ -119,13 +114,11 @@ class GitHub {
data.conclusion = result; data.conclusion = result;
} }
if (CloudRunner.isCloudRunnerAsyncEnvironment) { if (await CloudRunnerOptions.asyncCloudRunner) {
CloudRunnerLogger.log(`Updating check via async update workflow`);
await GitHub.runUpdateAsyncChecksWorkflow(data, `update`); await GitHub.runUpdateAsyncChecksWorkflow(data, `update`);
return; return;
} }
CloudRunnerLogger.log(`Updating check via direct call`);
await GitHub.updateGitHubCheckRequest(data); await GitHub.updateGitHubCheckRequest(data);
} }
@ -141,16 +134,18 @@ class GitHub {
if (mode === `create`) { if (mode === `create`) {
throw new Error(`Not supported: only use update`); throw new Error(`Not supported: only use update`);
} }
const workflowsResult = await GitHub.octokitPAT.request(`GET /repos/{owner}/{repo}/actions/workflows`, { const workflowsResult = await GitHub.octokitDefaultToken.request(
owner: GitHub.owner, `GET /repos/${GitHub.owner}/${GitHub.repo}/actions/workflows`,
repo: GitHub.repo, {
}); owner: GitHub.owner,
repo: GitHub.repo,
},
);
const workflows = workflowsResult.data.workflows; const workflows = workflowsResult.data.workflows;
CloudRunnerLogger.log(`Got ${workflows.length} workflows`);
let selectedId = ``; let selectedId = ``;
for (let index = 0; index < workflowsResult.data.total_count; index++) { for (let index = 0; index < workflowsResult.data.total_count; index++) {
if (workflows[index].name === GitHub.asyncChecksApiWorkflowName) { if (workflows[index].name === GitHub.asyncChecksApiWorkflowName) {
selectedId = workflows[index].id.toString(); selectedId = workflows[index].id;
} }
} }
if (selectedId === ``) { if (selectedId === ``) {
@ -168,37 +163,6 @@ class GitHub {
}, },
}); });
} }
static async triggerWorkflowOnComplete(triggerWorkflowOnComplete: string[]) {
const workflowsResult = await GitHub.octokitPAT.request(`GET /repos/{owner}/{repo}/actions/workflows`, {
owner: GitHub.owner,
repo: GitHub.repo,
});
const workflows = workflowsResult.data.workflows;
CloudRunnerLogger.log(`Got ${workflows.length} workflows`);
for (const element of triggerWorkflowOnComplete) {
let selectedId = ``;
for (let index = 0; index < workflowsResult.data.total_count; index++) {
if (workflows[index].name === element) {
selectedId = workflows[index].id.toString();
}
}
if (selectedId === ``) {
core.info(JSON.stringify(workflows));
throw new Error(`no workflow with name "${GitHub.asyncChecksApiWorkflowName}"`);
}
await GitHub.octokitPAT.request(`POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches`, {
owner: GitHub.owner,
repo: GitHub.repo,
// eslint-disable-next-line camelcase
workflow_id: selectedId,
ref: CloudRunnerOptions.branch,
inputs: {
buildGuid: CloudRunner.buildParameters.buildGuid,
},
});
}
}
} }
export default GitHub; export default GitHub;

View File

@ -64,8 +64,8 @@ class Input {
static get gitSha() { static get gitSha() {
if (Input.getInput(`GITHUB_SHA`)) { if (Input.getInput(`GITHUB_SHA`)) {
return Input.getInput(`GITHUB_SHA`); return Input.getInput(`GITHUB_SHA`);
} else if (Input.getInput(`GitSha`)) { } else if (Input.getInput(`GitSHA`)) {
return Input.getInput(`GitSha`); return Input.getInput(`GitSHA`);
} }
} }
@ -74,7 +74,7 @@ class Input {
} }
static get runNumber() { static get runNumber() {
return Input.getInput('GITHUB_RUN_NUMBER') || Input.getInput('runNumber') || '0'; return Input.getInput('GITHUB_RUN_NUMBER') || '0';
} }
static get targetPlatform() { static get targetPlatform() {
@ -168,7 +168,7 @@ class Input {
} }
static get gitPrivateToken() { static get gitPrivateToken() {
return Input.getInput('gitPrivateToken') || false; return core.getInput('gitPrivateToken') || false;
} }
static get chownFilesTo() { static get chownFilesTo() {