diff --git a/src/commands/actors/push.ts b/src/commands/actors/push.ts index 298c437e3..4c6daffb3 100644 --- a/src/commands/actors/push.ts +++ b/src/commands/actors/push.ts @@ -40,6 +40,18 @@ const DEFAULT_ACTOR_VERSION_NUMBER = '0.0'; // that changes, we have to add it. const DEFAULT_BUILD_TAG = 'latest'; +// Default standby mode configuration when usesStandbyMode is enabled in actor.json +const DEFAULT_STANDBY_OPTIONS = { + isEnabled: true, + disableStandbyFieldsOverride: false, + maxRequestsPerActorRun: 4, + desiredRequestsPerActorRun: 3, + idleTimeoutSecs: 300, + build: 'latest', + memoryMbytes: 1024, + shouldPassActorInput: false, +}; + export class ActorsPushCommand extends ApifyCommand { static override name = 'push' as const; @@ -196,6 +208,12 @@ export class ActorsPushCommand extends ApifyCommand { }, ], }; + + // Enable standby mode if configured in actor.json + if (actorConfig!.usesStandbyMode) { + newActor.actorStandby = DEFAULT_STANDBY_OPTIONS as ActorCollectionCreateOptions['actorStandby']; + } + actor = await apifyClient.actors().create(newActor); actorId = actor.id; isActorCreatedNow = true; @@ -203,10 +221,17 @@ export class ActorsPushCommand extends ApifyCommand { } } + const actorClient = apifyClient.actor(actorId); + + // Update standby mode on existing actor if configured in actor.json but not enabled on actor + if (!isActorCreatedNow && actorConfig!.usesStandbyMode && !actor.actorStandby?.isEnabled) { + await actorClient.update({ actorStandby: DEFAULT_STANDBY_OPTIONS }); + info({ message: 'Enabled standby mode for Actor.' }); + } + info({ message: `Deploying Actor '${actorConfig!.name}' to Apify.` }); const filesSize = await sumFilesSizeInBytes(filePathsToPush, cwd); - const actorClient = apifyClient.actor(actorId); let sourceType; let sourceFiles; diff --git a/test/api/commands/push.test.ts b/test/api/commands/push.test.ts index 5f07c5bf2..166f9ea70 100644 --- a/test/api/commands/push.test.ts +++ b/test/api/commands/push.test.ts @@ -349,4 +349,108 @@ describe('[api] apify push', () => { }, TEST_TIMEOUT, ); + + it( + 'should enable standby mode when usesStandbyMode is true in actor.json', + async () => { + toggleCwdBetweenFullAndParentPath(); + + const standbyActorName = `${ACTOR_NAME}-standby`; + + await mkdir(joinCwdPath(standbyActorName), { recursive: true }); + forceNewCwd(standbyActorName); + + // Create a minimal actor with usesStandbyMode enabled + const actorJson = { + actorSpecification: 1, + name: standbyActorName, + version: '0.0', + buildTag: 'latest', + usesStandbyMode: true, + }; + + await writeFile(joinPath(LOCAL_CONFIG_PATH), JSON.stringify(actorJson, null, '\t')); + + await testRunCommand(ActorsPushCommand, { flags_noPrompt: true, flags_force: true }); + + const userInfo = await getLocalUserInfo(); + const actorId = `${userInfo.username}/${standbyActorName}`; + actorsForCleanup.add(actorId); + const createdActorClient = testUserClient.actor(actorId); + const createdActor = await createdActorClient.get(); + + // Verify all standby options are set to default values + expect(createdActor?.actorStandby).to.be.eql({ + isEnabled: true, + disableStandbyFieldsOverride: false, + maxRequestsPerActorRun: 4, + desiredRequestsPerActorRun: 3, + idleTimeoutSecs: 300, + build: 'latest', + memoryMbytes: 1024, + shouldPassActorInput: false, + }); + + if (createdActor) await createdActorClient.delete(); + }, + TEST_TIMEOUT, + ); + + it( + 'should enable standby mode on existing actor when usesStandbyMode is true in actor.json', + async () => { + toggleCwdBetweenFullAndParentPath(); + + // Create an actor without standby mode first + const testActorWithoutStandby = { + ...TEST_ACTOR, + name: `${ACTOR_NAME}-standby-update`, + }; + const testActor = await testUserClient.actors().create(testActorWithoutStandby); + actorsForCleanup.add(testActor.id); + const testActorClient = testUserClient.actor(testActor.id); + + // Verify standby is not enabled initially + const initialActor = await testActorClient.get(); + expect(initialActor?.actorStandby?.isEnabled).to.not.be.eql(true); + + await mkdir(joinCwdPath(testActorWithoutStandby.name), { recursive: true }); + forceNewCwd(testActorWithoutStandby.name); + + // Create actor.json with usesStandbyMode enabled + const actorJson = { + actorSpecification: 1, + name: testActorWithoutStandby.name, + version: '0.0', + buildTag: 'latest', + usesStandbyMode: true, + }; + + await writeFile(joinPath(LOCAL_CONFIG_PATH), JSON.stringify(actorJson, null, '\t')); + + // Push to existing actor - this should update standby mode + await testRunCommand(ActorsPushCommand, { + args_actorId: testActor.id, + flags_noPrompt: true, + flags_force: true, + }); + + const updatedActor = await testActorClient.get(); + + // Verify all standby options are set to default values + expect(updatedActor?.actorStandby).to.be.eql({ + isEnabled: true, + disableStandbyFieldsOverride: false, + maxRequestsPerActorRun: 4, + desiredRequestsPerActorRun: 3, + idleTimeoutSecs: 300, + build: 'latest', + memoryMbytes: 1024, + shouldPassActorInput: false, + }); + + if (updatedActor) await testActorClient.delete(); + }, + TEST_TIMEOUT, + ); });