forked from kamranayub/wait-for-netlify-action
-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
index.js
145 lines (115 loc) · 4.2 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const core = require('@actions/core');
const github = require('@actions/github');
const axios = require('axios');
const READY_STATES = ['ready', 'current'];
function getNetlifyUrl(url) {
return axios.get(url, {
headers: {
Authorization: `Bearer ${process.env.NETLIFY_TOKEN}`,
},
});
}
const waitForDeployCreation = (url, commitSha, MAX_TIMEOUT, context) => {
const increment = 15;
return new Promise((resolve, reject) => {
let elapsedTimeSeconds = 0;
const handle = setInterval(async () => {
elapsedTimeSeconds += increment;
if (elapsedTimeSeconds >= MAX_TIMEOUT) {
clearInterval(handle);
return reject(`Timeout reached: Deployment was not created within ${MAX_TIMEOUT} seconds.`);
}
const { data: netlifyDeployments } = await getNetlifyUrl(url);
if (!netlifyDeployments) {
return reject(`Failed to get deployments for site`);
}
const commitDeployment = netlifyDeployments.find((d) => d.commit_ref === commitSha && (!context || d.context === context));
if (commitDeployment) {
clearInterval(handle);
return resolve(commitDeployment);
}
console.log(`Not yet created, waiting ${increment} more seconds...`);
}, increment * 1000);
});
};
const waitForReadiness = (url, MAX_TIMEOUT) => {
const increment = 30;
return new Promise((resolve, reject) => {
let elapsedTimeSeconds = 0;
let state;
const handle = setInterval(async () => {
elapsedTimeSeconds += increment;
if (elapsedTimeSeconds >= MAX_TIMEOUT) {
clearInterval(handle);
return reject(
`Timeout reached: Deployment was not ready within ${MAX_TIMEOUT} seconds. Last known deployment state: ${state}.`
);
}
const { data: deploy } = await getNetlifyUrl(url);
state = deploy.state;
if (READY_STATES.includes(state)) {
clearInterval(handle);
return resolve();
}
console.log(`Not yet ready, waiting ${increment} more seconds...`);
}, increment * 1000);
});
};
const waitForUrl = async (url, MAX_TIMEOUT) => {
const iterations = MAX_TIMEOUT / 3;
for (let i = 0; i < iterations; i++) {
try {
await axios.get(url);
return;
} catch (e) {
console.log(`URL ${url} unavailable, retrying...`);
await new Promise((r) => setTimeout(r, 3000));
}
}
core.setFailed(`Timeout reached: Unable to connect to ${url}`);
};
const run = async () => {
try {
const netlifyToken = process.env.NETLIFY_TOKEN;
const commitSha =
github.context.eventName === 'pull_request' ? github.context.payload.pull_request.head.sha : github.context.sha;
const MAX_CREATE_TIMEOUT = 60 * 5; // 5 min
const MAX_WAIT_TIMEOUT = 60 * 15; // 15 min
const MAX_READY_TIMEOUT = Number(core.getInput('max_timeout')) || 60;
const siteId = core.getInput('site_id');
const context = core.getInput('context');
if (!netlifyToken) {
core.setFailed('Please set NETLIFY_TOKEN env variable to your Netlify Personal Access Token secret');
}
if (!commitSha) {
core.setFailed('Could not determine GitHub commit');
}
if (!siteId) {
core.setFailed('Required field `site_id` was not provided');
}
let message = `Waiting for Netlify to create a deployment for git SHA ${commitSha}`;
if (context) {
message += ` and context ${context}`
}
console.log(message);
const commitDeployment = await waitForDeployCreation(
`https://api.netlify.com/api/v1/sites/${siteId}/deploys`,
commitSha,
MAX_CREATE_TIMEOUT,
context
);
const url = `https://${commitDeployment.id}--${commitDeployment.name}.netlify.app`;
core.setOutput('deploy_id', commitDeployment.id);
core.setOutput('url', url);
console.log(`Waiting for Netlify deployment ${commitDeployment.id} in site ${commitDeployment.name} to be ready`);
await waitForReadiness(
`https://api.netlify.com/api/v1/sites/${siteId}/deploys/${commitDeployment.id}`,
MAX_WAIT_TIMEOUT
);
console.log(`Waiting for a 200 from: ${url}`);
await waitForUrl(url, MAX_READY_TIMEOUT);
} catch (error) {
core.setFailed(typeof error === 'string' ? error : error.message);
}
};
run();