forked from quantizor/wait-for-netlify-action
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
137 lines (109 loc) · 4 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
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) => {
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);
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');
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');
}
console.log(`Waiting for Netlify to create a deployment for git SHA ${commitSha}`);
const commitDeployment = await waitForDeployCreation(
`https://api.netlify.com/api/v1/sites/${siteId}/deploys`,
commitSha,
MAX_CREATE_TIMEOUT
);
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();