1import Apify from 'apify';
2
3const { utils: { log, sleep } } = Apify;
4
5Apify.main(async () => {
6
7 const client = Apify.newClient();
8 const { items: actors } = await client.actors().list();
9 const { batchType, actorNameContains, actorIds } = await Apify.getInput();
10
11 let batchTypeDescription = "";
12 let targetActors = [];
13 let actorCount = 0;
14 let totalBuildsFinished = 0;
15 let requestsCount = 0;
16
17 let results = {
18 "builds": [],
19 "stats": {
20 "total": 0,
21 "failed": 0,
22 "succeeded": 0,
23 "requests": 0
24 }
25 };
26
27
28 async function prepTargetActors() {
29 for (const item in actors) {
30 if (batchType == "actorNameContains" && actors[item].name.includes(actorNameContains)) {
31 targetActors.push(actors[item]);
32 batchTypeDescription = "matching part of the actor name.";
33 }
34 else if (batchType == "actorIds" && actorIds.includes(actors[item].id)) {
35 targetActors.push(actors[item]);
36 batchTypeDescription = "matching selected actor ids.";
37 }
38 else if (batchType == "all") {
39 targetActors.push(actors[item]);
40 batchTypeDescription = "for all actors in the account.";
41 }
42 }
43 log.info(`Starting builds ${batchTypeDescription}`);
44 log.info('–––––––––––––––––––––––––––––––––––––––––');
45 }
46
47
48 async function buildActors(targetActors) {
49 let actorsInProgress = [];
50 for (const item in targetActors) {
51 actorCount++;
52 await sleep(1000);
53 const { id: actorId, name: actorName } = targetActors[item];
54 const actor = client.actor(actorId);
55
56 try {
57 const startBuild = await actor.build('0.0');
58 requestsCount++;
59
60 log.info(`${actorCount}.`);
61 log.info(`actor name: ${actorName}`);
62 log.info(`build id: ${startBuild.id}`);
63 log.info(`started at: ${startBuild.startedAt}`);
64 log.info(`status: ${startBuild.status}`);
65 log.info('–––––––––––––––––––––––––––––––––––––––––');
66
67 actorsInProgress.push(targetActors[item]);
68
69 } catch (error) {
70 actorCount--;
71
72 log.warning(`skipping actor ${actorName} due to ${error.type}.`);
73 log.warning(`actor id: ${actorId}`);
74 log.info('–––––––––––––––––––––––––––––––––––––––––');
75 }
76 }
77 log.info(`builds started for ${actorCount} actors.`);
78 log.info('waiting for builds to finish...');
79 log.info('–––––––––––––––––––––––––––––––––––––––––');
80
81 return actorsInProgress;
82 };
83
84
85 async function checkBuilds(targetActor) {
86 const actor = client.actor(targetActor.id);
87 const { id: actorId, name: actorName, buildtag: actorBuildTag } = await actor.get();
88 requestsCount++;
89
90 let buildFinshed = false;
91 while (!buildFinshed) {
92 await sleep(delay);
93 requestsCount++;
94 const { items: actorBuilds } = await actor.builds().list({ 'desc': true });
95 const buildInProgress = actorBuilds[0];
96
97 let result = { ...buildInProgress, actorId, actorName, actorBuildTag };
98
99 if (buildInProgress.status == 'RUNNING') {
100 buildFinshed = false;
101
102 } else if (buildInProgress.status == 'SUCCEEDED') {
103 results.stats.total++;
104 results.stats.succeeded++;
105
106 buildFinshed = true;
107 totalBuildsFinished++;
108 results.builds.push(result);
109
110 log.info(`${totalBuildsFinished} of ${actorCount}`);
111 log.info(`actor name: ${actorName}`);
112 log.info(`finished at: ${buildInProgress.finishedAt}`);
113 log.info(`status: ${buildInProgress.status}`);
114 log.info('–––––––––––––––––––––––––––––––––––––––––');
115
116 } else if (buildInProgress.status == 'FAILED') {
117 results.stats.total++;
118 results.stats.failed++;
119
120 buildFinshed = true;
121 totalBuildsFinished++;
122 results.builds.push(result);
123
124 log.info(`${totalBuildsFinished} of ${actorCount}`);
125 log.error(`actor name: ${actorName}`);
126 log.error(`finished at: ${buildInProgress.finishedAt}`);
127 log.error(`status: ${buildInProgress.status}`);
128 log.info('–––––––––––––––––––––––––––––––––––––––––');
129 }
130 }
131 }
132
133 async function startChecks(actorsInProgress) {
134 for (const item in actorsInProgress) {
135 checkBuilds(actorsInProgress[item]);
136 }
137 while (totalBuildsFinished != actorsInProgress.length) {
138 await sleep(delay);
139 }
140 results.stats.requests = requestsCount;
141 }
142
143
144 await prepTargetActors();
145 let actorsInProgress = await buildActors(targetActors.slice(0));
146 let delay = (actorCount > 0) ? 10000 : 0;
147 await sleep(delay);
148 await startChecks(actorsInProgress);
149
150 log.info('Done.');
151 log.info(`total builds requested: ${results.stats.total}`);
152 log.info(`total builds successful: ${results.stats.succeeded}`);
153 log.info(`total builds failed: ${results.stats.failed}`);
154 log.info(`total API calls: ${results.stats.requests}`);
155
156 const store = await Apify.openKeyValueStore();
157 await store.setValue('STATS', results.stats);
158 await Apify.pushData(results.builds);
159});