Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/commands/actors/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { ACTOR_JOB_STATUSES } from '@apify/consts';
import { ApifyCommand, StdinMode } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { Flags } from '../../lib/command-framework/flags.js';
import { consoleRunUrl } from '../../lib/commands/agent-output.js';
import { getInputOverride } from '../../lib/commands/resolve-input.js';
import { runActorOrTaskOnCloud, SharedRunOnCloudFlags } from '../../lib/commands/run-on-cloud.js';
import { finalizeRun, runUrl } from '../../lib/commands/run-result.js';
import { finalizeRun } from '../../lib/commands/run-result.js';
import { CommandExitCodes, LOCAL_CONFIG_PATH } from '../../lib/consts.js';
import { error, simpleLog } from '../../lib/outputs.js';
import { getLocalConfig, getLocalUserInfo, getLoggedClientOrThrow, TimestampFormatter } from '../../lib/utils.js';
Expand Down Expand Up @@ -176,7 +177,7 @@ export class ActorsCallCommand extends ApifyCommand<typeof ActorsCallCommand> {

// A *lot* is copied from `runs info`
if (!this.flags.silent) {
const url = runUrl(actorId, yieldedRun.id);
const url = consoleRunUrl(actorId, yieldedRun.id);

const message: string[] = [`${chalk.yellow('Started')}: ${TimestampFormatter.display(yieldedRun.startedAt)}`];

Expand Down
26 changes: 11 additions & 15 deletions src/commands/actors/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@ import { readFileSync, statSync, unlinkSync } from 'node:fs';
import { join, resolve } from 'node:path';
import process from 'node:process';

import type { Actor, ActorCollectionCreateOptions, ActorDefaultRunOptions } from 'apify-client';
import type { Actor, ActorCollectionCreateOptions, ActorDefaultRunOptions, Build } from 'apify-client';
import open from 'open';

import { fetchManifest } from '@apify/actor-templates';
import {
ACTOR_JOB_STATUSES,
ACTOR_JOB_TERMINAL_STATUSES,
ACTOR_SOURCE_TYPES,
MAX_MULTIFILE_BYTES,
} from '@apify/consts';
import { ACTOR_JOB_STATUSES, ACTOR_JOB_TYPES, ACTOR_SOURCE_TYPES, MAX_MULTIFILE_BYTES } from '@apify/consts';
import { createHmacSignature } from '@apify/utilities';

import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { Flags } from '../../lib/command-framework/flags.js';
import { isTerminalStatus } from '../../lib/commands/agent-output.js';
import { CommandExitCodes, DEPRECATED_LOCAL_CONFIG_NAME, LOCAL_CONFIG_PATH } from '../../lib/consts.js';
import { sumFilesSizeInBytes } from '../../lib/files.js';
import { useAbortJobOnSignal } from '../../lib/hooks/useAbortJobOnSignal.js';
Expand Down Expand Up @@ -441,7 +437,7 @@ Skipping push. Use --force to override.`,
// share one budget. Without this, a log stream that dies near the cap
// would let the poll loop wait another full --wait-for-finish on top.
const deadline = waitForFinishMillis === undefined ? Infinity : Date.now() + waitForFinishMillis;
let build = await actorClient.build(version, {
let build: Build | undefined = await actorClient.build(version, {
useCache: true,
waitForFinish: 2, // NOTE: We need to wait some time to Apify open stream and we can create connection
});
Expand All @@ -451,7 +447,7 @@ Skipping push. Use --force to override.`,
// build doesn't keep running after the user gives up waiting.
using _signalHandler = useAbortJobOnSignal({
apifyClient,
kind: 'build',
kind: ACTOR_JOB_TYPES.BUILD,
jobId: build.id,
});

Expand All @@ -463,18 +459,18 @@ Skipping push. Use --force to override.`,
console.error(err);
}

const refreshedBuild = await apifyClient.build(build.id).get();
if (!refreshedBuild) {
error({ message: `Could not fetch build with ID "${build.id}" after deployment.` });
const buildId = build.id;
build = await apifyClient.build(buildId).get();
if (!build) {
error({ message: `Could not fetch build with ID "${buildId}" after deployment.` });
process.exitCode = CommandExitCodes.BuildFailed;
return;
}
build = refreshedBuild;

// `outputJobLog` can return before the build is actually terminal (stream
// ended early, timeout hit). Poll the remaining budget so the status
// branches below see the real outcome.
while (!ACTOR_JOB_TERMINAL_STATUSES.includes(build.status as never) && Date.now() < deadline) {
while (!isTerminalStatus(build.status) && Date.now() < deadline) {
await new Promise((resolve) => setTimeout(resolve, 1000));
build = (await apifyClient.build(build.id).get())!;
}
Expand Down Expand Up @@ -507,7 +503,7 @@ Skipping push. Use --force to override.`,
const outcome = resolvePushOutcome(buildStatus);

const actorUrl = `https://console.apify.com${redirectUrlPart}/actors/${build.actId}`;
const buildUrl = `${actorUrl}#/builds/${build.buildNumber}`;
const buildUrl = `${actorUrl}/builds/${build.buildNumber}`;

// Surface the tail of the build log as the failure reason. Best-effort:
// the build status already conveys the outcome if the log can't be read.
Expand Down
4 changes: 2 additions & 2 deletions src/commands/actors/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chalk from 'chalk';
import { ApifyCommand, StdinMode } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { Flags } from '../../lib/command-framework/flags.js';
import { consoleRunUrl } from '../../lib/commands/agent-output.js';
import { consoleActorUrl, consoleRunUrl } from '../../lib/commands/agent-output.js';
import { getInputOverride } from '../../lib/commands/resolve-input.js';
import { runActorOrTaskOnCloud, SharedRunOnCloudFlags } from '../../lib/commands/run-on-cloud.js';
import { LOCAL_CONFIG_PATH } from '../../lib/consts.js';
Expand Down Expand Up @@ -141,7 +141,7 @@ export class ActorsStartCommand extends ApifyCommand<typeof ActorsStartCommand>
waited: false,
actor: {
id: actorId,
url: `https://console.apify.com/actors/${actorId}`,
url: consoleActorUrl(actorId),
},
run: {
id: run.id,
Expand Down
14 changes: 8 additions & 6 deletions src/commands/builds/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import process from 'node:process';

import chalk from 'chalk';

import { ACTOR_JOB_STATUSES, ACTOR_JOB_TYPES } from '@apify/consts';

import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { Flags } from '../../lib/command-framework/flags.js';
Expand Down Expand Up @@ -157,7 +159,7 @@ export class BuildsCreateCommand extends ApifyCommand<typeof BuildsCreateCommand
// The `using` binding removes the listener when the block exits.
using _signalHandler = useAbortJobOnSignal({
apifyClient: client,
kind: 'build',
kind: ACTOR_JOB_TYPES.BUILD,
jobId: build.id,
});

Expand All @@ -179,16 +181,16 @@ export class BuildsCreateCommand extends ApifyCommand<typeof BuildsCreateCommand
const { job } = await waitForTerminalStatus({
apifyClient: client,
jobId: build.id,
kind: 'build',
kind: ACTOR_JOB_TYPES.BUILD,
});
build = job as typeof build;
build = job;
}

const reachedTerminal = log || wait;

if (reachedTerminal) {
const ok = build.status === 'SUCCEEDED';
const exitCode = exitCodeForJobStatus(build.status, 'build');
const ok = build.status === ACTOR_JOB_STATUSES.SUCCEEDED;
const exitCode = exitCodeForJobStatus(build.status, ACTOR_JOB_TYPES.BUILD);
const logTail = ok ? [] : await fetchLogTail(client, build.id);

if (json) {
Expand Down Expand Up @@ -224,7 +226,7 @@ export class BuildsCreateCommand extends ApifyCommand<typeof BuildsCreateCommand
simpleLog({
message: formatResultSummary({
resultLabel: 'Apify build result',
overallStatus: build.status as never,
overallStatus: build.status,
lines: [
{ label: 'Build', value: build.status },
{ label: 'Build ID', value: build.id },
Expand Down
3 changes: 2 additions & 1 deletion src/commands/builds/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import chalk from 'chalk';

import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { consoleBuildUrl } from '../../lib/commands/agent-output.js';
import { prettyPrintBytes } from '../../lib/commands/pretty-print-bytes.js';
import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js';
import { error, simpleLog } from '../../lib/outputs.js';
Expand Down Expand Up @@ -103,7 +104,7 @@ export class BuildsInfoCommand extends ApifyCommand<typeof BuildsInfoCommand> {

message.push('');

const url = `https://console.apify.com/actors/${build.actId}/builds/${build.buildNumber}`;
const url = consoleBuildUrl(build.actId, build.buildNumber);

message.push(`${chalk.blue('View in Apify Console')}: ${url}`);

Expand Down
12 changes: 6 additions & 6 deletions src/commands/builds/wait.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import process from 'node:process';

import type { Build } from 'apify-client';
import { ACTOR_JOB_STATUSES, ACTOR_JOB_TYPES } from '@apify/consts';

import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
Expand Down Expand Up @@ -65,15 +65,15 @@ export class BuildsWaitCommand extends ApifyCommand<typeof BuildsWaitCommand> {
const { job, timedOutWaiting } = await waitForTerminalStatus({
apifyClient,
jobId: buildId,
kind: 'build',
kind: ACTOR_JOB_TYPES.BUILD,
maxWaitMillis: timeout ? timeout * 1000 : undefined,
pollIntervalMillis: pollInterval ? pollInterval * 1000 : undefined,
});
const build = job as Build;
const build = job;

const url = consoleBuildUrl(build.actId, build.buildNumber);
const ok = build.status === 'SUCCEEDED';
const exitCode = exitCodeForWaitResult({ job, timedOutWaiting }, 'build');
const ok = build.status === ACTOR_JOB_STATUSES.SUCCEEDED;
const exitCode = exitCodeForWaitResult({ job, timedOutWaiting }, ACTOR_JOB_TYPES.BUILD);
const giveUpMessage = `Gave up waiting after ${timeout}s; build is still ${build.status}`;

let logTail: string[] = [];
Expand Down Expand Up @@ -119,7 +119,7 @@ export class BuildsWaitCommand extends ApifyCommand<typeof BuildsWaitCommand> {
simpleLog({
message: formatResultSummary({
resultLabel: 'Apify build result',
overallStatus: build.status as never,
overallStatus: build.status,
lines,
links,
errorReason: ok ? undefined : logTail,
Expand Down
7 changes: 4 additions & 3 deletions src/commands/runs/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import chalk from 'chalk';
import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
import { Flags } from '../../lib/command-framework/flags.js';
import { consoleDatasetUrl, consoleKeyValueStoreUrl, consoleRunUrl } from '../../lib/commands/agent-output.js';
import { prettyPrintBytes } from '../../lib/commands/pretty-print-bytes.js';
import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js';
import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js';
Expand Down Expand Up @@ -258,9 +259,9 @@ export class RunsInfoCommand extends ApifyCommand<typeof RunsInfoCommand> {

message.push('');

const url = `https://console.apify.com/actors/${run.actId}/runs/${run.id}`;
const datasetUrl = `https://console.apify.com/storage/datasets/${run.defaultDatasetId}`;
const keyValueStoreUrl = `https://console.apify.com/storage/key-value-stores/${run.defaultKeyValueStoreId}`;
const url = consoleRunUrl(run.actId, run.id);
const datasetUrl = consoleDatasetUrl(run.defaultDatasetId);
const keyValueStoreUrl = consoleKeyValueStoreUrl(run.defaultKeyValueStoreId);

message.push(`${chalk.blue('Export results')}: ${datasetUrl}`);
message.push(`${chalk.blue('View saved items')}: ${keyValueStoreUrl}`);
Expand Down
12 changes: 6 additions & 6 deletions src/commands/runs/wait.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import process from 'node:process';

import type { ActorRun } from 'apify-client';
import { ACTOR_JOB_STATUSES, ACTOR_JOB_TYPES } from '@apify/consts';

import { ApifyCommand } from '../../lib/command-framework/apify-command.js';
import { Args } from '../../lib/command-framework/args.js';
Expand Down Expand Up @@ -70,15 +70,15 @@ export class RunsWaitCommand extends ApifyCommand<typeof RunsWaitCommand> {
const { job, timedOutWaiting } = await waitForTerminalStatus({
apifyClient,
jobId: runId,
kind: 'run',
kind: ACTOR_JOB_TYPES.RUN,
maxWaitMillis: timeout ? timeout * 1000 : undefined,
pollIntervalMillis: pollInterval ? pollInterval * 1000 : undefined,
});
const run = job as ActorRun;
const run = job;

const url = consoleRunUrl(run.actId, run.id);
const ok = run.status === 'SUCCEEDED';
const exitCode = exitCodeForWaitResult({ job, timedOutWaiting }, 'run');
const ok = run.status === ACTOR_JOB_STATUSES.SUCCEEDED;
const exitCode = exitCodeForWaitResult({ job, timedOutWaiting }, ACTOR_JOB_TYPES.RUN);
const giveUpMessage = `Gave up waiting after ${timeout}s; run is still ${run.status}`;

let logTail: string[] = [];
Expand Down Expand Up @@ -131,7 +131,7 @@ export class RunsWaitCommand extends ApifyCommand<typeof RunsWaitCommand> {
simpleLog({
message: formatResultSummary({
resultLabel: 'Apify run result',
overallStatus: run.status as never,
overallStatus: run.status,
lines,
links,
errorReason: ok ? undefined : logTail,
Expand Down
Loading
Loading