-
Notifications
You must be signed in to change notification settings - Fork 18
/
notify-about-fixtures-changes.js
159 lines (123 loc) Β· 5.66 KB
/
notify-about-fixtures-changes.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
module.exports = notifyAboutFixturesChanges
const querystring = require('querystring')
const axios = require('axios')
const {diff: getDiff, diffString} = require('json-diff')
const env = require('./env')
async function notifyAboutFixturesChanges (diffs) {
console.log('')
console.log('π€ Fixture changes detected in cron job. Creating pull request ...')
// https://docs.travis-ci.com/user/environment-variables/
const repoName = env.TRAVIS_REPO_SLUG
const github = axios.create({
baseURL: 'https://api.github.com',
headers: {
common: {
authorization: `token ${env.FIXTURES_USER_A_TOKEN_FULL_ACCESS}`
}
}
})
// who am I?
const {data: {login}} = await github.get('/user')
console.log(`π€ Signed in as ${login}. Looking if I already created a pull request`)
// Do I have a pending pull request?
const query = querystring.stringify({
type: 'pr',
author: login,
is: 'open',
repo: repoName
}, ' ', ':')
const {data: pullRequestsResult} = await github.get(`/search/issues?q=${query}`)
const pullRequestNumbers = pullRequestsResult.items.map(pr => pr.number)
// if there are more than a single pull request, then we have a problem, because
// I donβt know which one to update. So Iβll ask you for help :)
if (pullRequestsResult.total_count > 1) {
console.log('π€π Oh oh, I donβt know how to handle more than one pull requests. Creating an issue for my human friends')
const result = await github.post(`/repos/${repoName}/issues`, {
title: 'π€π Too many PRs',
body: `Dearest humans,
Iβve run into a problem here. My friend Travis notified that something changed in GitHubβs APIs. I would usually create a new pull request to let you know about it, or update an existing one. But now there more than one: ${pullRequestNumbers.map(number => `#${number}`).join(', ')}
I donβt know how that happened, did I short-circuit again?
You could really help me by closing all pull requests or leave the one open you want me to keep updating.
For the time being, these are the changes I have found:
${diffsToIssueBody(repoName, diffs)}
Hope you can fix it (and my circuits) soon π`
})
const {data: {html_url: issueUrl}} = result
console.log(`π€π issue created: ${issueUrl}`)
return
}
if (pullRequestsResult.total_count === 1) {
const pullRequest = pullRequestsResult.items[0]
console.log(`π€ Existing pull-request found: ${pullRequest.html_url}`)
const {data} = await github.get(`/repos/${repoName}/pulls/${pullRequest.number}`)
const branchName = data.head.ref
await updateFixtures({diffs, github, repoName, branchName})
console.log(`π€ pull-request updated: ${pullRequest.html_url}`)
return
}
console.log('π€ No existing pull request found')
console.log(`π€ Looking for last commit sha of ${repoName}/git/refs/heads/master`)
const {data: {object: {sha}}} = await github.get(`/repos/${repoName}/git/refs/heads/master`)
// const branchName = `cron/fixtures-changes/${new Date().toISOString().substr(0, 10)}`
const branchName = `cron/fixtures-changes/${new Date().toISOString().substr(0, 10)}`
console.log(`π€ Creating new branch: ${branchName} using last sha ${sha}`)
await github.post(`/repos/${repoName}/git/refs`, {
ref: `refs/heads/${branchName}`,
sha
})
await updateFixtures({diffs, github, repoName, branchName})
const {data} = await github.post(`/repos/${repoName}/pulls`, {
title: `π€π¨ ${diffs.length} changes in existing fixtures detected`,
head: branchName,
base: 'master',
body: `Dearest humans,
My friend Travis asked me to let you know that they found API changes in their daily routine check.`
})
console.log(`π€ Pull request created: ${data.html_url}`)
}
function diffsToIssueBody (diffs) {
return diffs.map(diff => {
return `<details>
<summary><strong>${diff.name}</strong></summary>
\`\`\`diff
${diffString(diff.oldNormalizedFixtures, diff.newNormalizedFixtures, {color: false}).trim()}
\`\`\`
</details>`
}).join('\n')
}
function updateFixtures ({diffs, github, repoName, branchName}) {
return diffs.reduce(async (promise, diff) => {
await promise
const fileApiPath = `/repos/${repoName}/contents/scenarios/${diff.name}/normalized-fixture.json?ref=${branchName}`
const fileContent = Buffer.from(JSON.stringify(diff.newNormalizedFixtures, null, 2) + '\n').toString('base64')
if (diff.changes[0][0] === '-') {
throw new Error(`π€π Looks like ${diff.name} is a new fixture, but that could not have come from a routine check?`)
}
console.log(`π€ Loading current fixture file for ${diff.name} from ${fileApiPath}`)
try {
await github.get(fileApiPath)
} catch (error) {
console.log(error.toString())
console.log(JSON.stringify(error.response.data, null, 2))
}
const {data} = await github.get(fileApiPath)
const existingContent = Buffer.from(data.content, 'base64').toString()
const diffToRemote = getDiff(diff.newNormalizedFixtures, JSON.parse(existingContent))
if (!diffToRemote) {
return console.log(`π€ ${diff.name} is up-to-date`)
}
console.log(`π€ Updating fixture file for ${diff.name}`)
const {data: {content}} = await github.put(fileApiPath, {
path: `scenarios/${diff.name}/normalized-fixture.json`,
content: fileContent,
branch: branchName,
sha: data.sha,
message: `fix(fixture): updated ${diff.name}
BREAKING CHANGE: ${diff.name} has changed
\`\`\`diff
${diffString(diff.oldNormalizedFixtures, diff.newNormalizedFixtures, {color: false}).trim()}
\`\`\``
})
console.log(`π€ ${diff.name} updated: ${content.html_url}`)
}, Promise.resolve())
}