From bc18be11036b04f1f00f715a8825b6f997aecd43 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 10:17:02 +0200 Subject: [PATCH 1/5] fix: list real Actor builds in Run Actor Build dropdown --- components/apify/apify.app.mjs | 54 +++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index 75ae9935a556f..2ddd48b6abaa4 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -1,3 +1,4 @@ +import { ACTOR_JOB_STATUSES } from "@apify/consts"; import { LIMIT } from "./common/constants.mjs"; import { ApifyClient } from "apify-client"; @@ -81,15 +82,54 @@ export default { buildTag: { type: "string", label: "Build", - description: "Specifies the Actor build to run. The accepted value is the build tag. If not provided, the default build will be used.", + description: "Actor build to run. Accepts a build tag (e.g. `latest`) or build number (e.g. `0.1.2`). Defaults to the Actor's default build.", async options({ actorId }) { - const { taggedBuilds } = await this.getActor({ - actorId, - }); + if (!actorId) { + return []; + } + + const [ + buildsResult, + actor, + ] = await Promise.all([ + this.listBuilds({ + actorId, + }), + this.getActor({ + actorId, + }), + ]); + + const builds = buildsResult?.items ?? []; + const taggedBuilds = actor?.taggedBuilds ?? {}; + + // Map build number -> tag names pointing at it (e.g. "latest", "beta"). + const tagsByBuildNumber = {}; + for (const [ + tag, + info, + ] of Object.entries(taggedBuilds)) { + if (info?.buildNumber) { + tagsByBuildNumber[info.buildNumber] ??= []; + tagsByBuildNumber[info.buildNumber].push(tag); + } + } - return Object.entries(taggedBuilds).map(([ - name, - ]) => name); + // Newest first. `buildNumberInt` is returned by the REST API for reliable + // ordering even though the apify-client type omits it. + return builds + .filter((build) => build.status === ACTOR_JOB_STATUSES.SUCCEEDED) + .sort((a, b) => (b.buildNumberInt ?? 0) - (a.buildNumberInt ?? 0)) + .map((build) => { + const tags = tagsByBuildNumber[build.buildNumber]; + const tagLabel = tags?.length + ? ` (${tags.join(", ")})` + : ""; + return { + label: `${build.buildNumber}${tagLabel}`, + value: build.buildNumber, + }; + }); }, }, clean: { From d2f49fe2aba3aa315010f0bdca5689ec6f182557 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 10:29:27 +0200 Subject: [PATCH 2/5] fix: resolve Build field by tag or build number --- components/apify/apify.app.mjs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index 2ddd48b6abaa4..8889eb14a5c6d 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -240,7 +240,7 @@ export default { return this._client().actor(actorId) .get(); }, - async getBuild(actorId, buildTag) { + async getBuild(actorId, buildRef) { // Get actor details const actor = await this._client().actor(actorId) .get(); @@ -249,20 +249,32 @@ export default { throw new Error(`Actor ${actorId} not found.`); } - if (!buildTag) { - buildTag = actor.defaultRunOptions.build; + if (!buildRef) { + buildRef = actor.defaultRunOptions.build; } - const { taggedBuilds } = actor; + const taggedBuilds = actor.taggedBuilds ?? {}; - if (taggedBuilds[buildTag]) { - return this._client().build(taggedBuilds[buildTag].buildId) + // Resolve by build tag (e.g. `latest`). + if (taggedBuilds[buildRef]?.buildId) { + return this._client().build(taggedBuilds[buildRef].buildId) .get(); - } else { - throw new Error( - `Actor ${actorId} has no build tagged "${buildTag}". Please build the actor first.`, - ); } + + // Fallback: resolve by build number (e.g. `0.1.2`) from the builds list. + const { items: builds = [] } = await this.listBuilds({ + actorId, + }); + const build = builds.find(({ buildNumber }) => buildNumber === buildRef); + + if (build) { + return this._client().build(build.id) + .get(); + } + + throw new Error( + `Actor ${actorId} has no build tagged or numbered "${buildRef}". Please build the actor first or pick an existing build.`, + ); }, listActors(opts = {}) { return this._client().store() From 535179e045e4f867dccb2ec4c9ca2a60544936fd Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 11:18:29 +0200 Subject: [PATCH 3/5] fix: accept build numbers in Run Actor Build field --- .../apify/actions/run-actor/run-actor.mjs | 9 +-- components/apify/apify.app.mjs | 74 ++++++------------- 2 files changed, 24 insertions(+), 59 deletions(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 2bb968289455f..f2dc48fc83b01 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -7,7 +7,7 @@ export default { key: "apify-run-actor", name: "Run Actor", description: "Performs an execution of a selected Actor in Apify. [See the documentation](https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor)", - version: "0.0.7", + version: "0.0.8", annotations: { destructiveHint: false, openWorldHint: true, @@ -300,12 +300,7 @@ export default { } if (buildTag) { - const taggedBuilds = actorDetails.taggedBuilds || {}; - if (!taggedBuilds[buildTag]) { - throw new Error( - `Build with tag "${buildTag}" was not found for actor "${actorDetails.title || actorDetails.name}".`, - ); - } + await apify.resolveBuildId(actorId, buildTag); } // Prepare input diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index 8889eb14a5c6d..f32ff62cb30c8 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -1,4 +1,3 @@ -import { ACTOR_JOB_STATUSES } from "@apify/consts"; import { LIMIT } from "./common/constants.mjs"; import { ApifyClient } from "apify-client"; @@ -82,54 +81,25 @@ export default { buildTag: { type: "string", label: "Build", - description: "Actor build to run. Accepts a build tag (e.g. `latest`) or build number (e.g. `0.1.2`). Defaults to the Actor's default build.", + description: "Actor build to run. Pick a tag from the list or enter a build number (e.g. `0.1.2`). Defaults to the Actor's default build.", async options({ actorId }) { if (!actorId) { return []; } - const [ - buildsResult, - actor, - ] = await Promise.all([ - this.listBuilds({ - actorId, - }), - this.getActor({ - actorId, - }), - ]); - - const builds = buildsResult?.items ?? []; - const taggedBuilds = actor?.taggedBuilds ?? {}; + const { taggedBuilds = {} } = await this.getActor({ + actorId, + }); - // Map build number -> tag names pointing at it (e.g. "latest", "beta"). - const tagsByBuildNumber = {}; - for (const [ + return Object.entries(taggedBuilds).map(([ tag, info, - ] of Object.entries(taggedBuilds)) { - if (info?.buildNumber) { - tagsByBuildNumber[info.buildNumber] ??= []; - tagsByBuildNumber[info.buildNumber].push(tag); - } - } - - // Newest first. `buildNumberInt` is returned by the REST API for reliable - // ordering even though the apify-client type omits it. - return builds - .filter((build) => build.status === ACTOR_JOB_STATUSES.SUCCEEDED) - .sort((a, b) => (b.buildNumberInt ?? 0) - (a.buildNumberInt ?? 0)) - .map((build) => { - const tags = tagsByBuildNumber[build.buildNumber]; - const tagLabel = tags?.length - ? ` (${tags.join(", ")})` - : ""; - return { - label: `${build.buildNumber}${tagLabel}`, - value: build.buildNumber, - }; - }); + ]) => ({ + label: info?.buildNumber + ? `${tag} (${info.buildNumber})` + : tag, + value: tag, + })); }, }, clean: { @@ -240,8 +210,7 @@ export default { return this._client().actor(actorId) .get(); }, - async getBuild(actorId, buildRef) { - // Get actor details + async resolveBuildId(actorId, buildRef) { const actor = await this._client().actor(actorId) .get(); @@ -255,27 +224,28 @@ export default { const taggedBuilds = actor.taggedBuilds ?? {}; - // Resolve by build tag (e.g. `latest`). if (taggedBuilds[buildRef]?.buildId) { - return this._client().build(taggedBuilds[buildRef].buildId) - .get(); + return taggedBuilds[buildRef].buildId; } - // Fallback: resolve by build number (e.g. `0.1.2`) from the builds list. const { items: builds = [] } = await this.listBuilds({ actorId, }); - const build = builds.find(({ buildNumber }) => buildNumber === buildRef); + const match = builds.find(({ buildNumber }) => buildNumber === buildRef); - if (build) { - return this._client().build(build.id) - .get(); + if (match) { + return match.id; } throw new Error( - `Actor ${actorId} has no build tagged or numbered "${buildRef}". Please build the actor first or pick an existing build.`, + `No build with tag or number "${buildRef}" found for actor ${actorId}.`, ); }, + async getBuild(actorId, buildRef) { + const buildId = await this.resolveBuildId(actorId, buildRef); + return this._client().build(buildId) + .get(); + }, listActors(opts = {}) { return this._client().store() .list(opts); From 06dd31513cb8dae618bb375777dde1bfabc6ec98 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 28 Jul 2026 11:00:52 +0200 Subject: [PATCH 4/5] chore: update version to 0.0.4 in run-actor component --- components/apify_oauth/actions/run-actor/run-actor.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify_oauth/actions/run-actor/run-actor.mjs b/components/apify_oauth/actions/run-actor/run-actor.mjs index 9c9084efa8621..7c08a389c33a8 100644 --- a/components/apify_oauth/actions/run-actor/run-actor.mjs +++ b/components/apify_oauth/actions/run-actor/run-actor.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "apify_oauth-run-actor", - version: "0.0.2", + version: "0.0.4", name, description, type, From 71b5a7368ee761b09652df67044f843b404e1121 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 18 Aug 2026 16:52:48 +0200 Subject: [PATCH 5/5] feat: enhance listBuilds method to accept options for sorting and limiting results --- components/apify/apify.app.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index f32ff62cb30c8..19c65dd18a71a 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -230,6 +230,8 @@ export default { const { items: builds = [] } = await this.listBuilds({ actorId, + desc: true, + limit: LIMIT, }); const match = builds.find(({ buildNumber }) => buildNumber === buildRef); @@ -262,10 +264,12 @@ export default { return this._client().tasks() .list(opts); }, - listBuilds({ actorId }) { + listBuilds({ + actorId, ...opts + }) { return this._client().actor(actorId) .builds() - .list(); + .list(opts); }, listKeyValueStores(opts = {}) { return this._client().keyValueStores()