Add update helper script (#117)
* Squashed commit from 'helper' branch * CI: run "update-helper" script on cron * Update index.js * disable proxy test * lint * re-add proxy test with delay * lint * Fix cron time
This commit is contained in:
parent
a1fe4802e6
commit
254dbefcd4
6 changed files with 226 additions and 2 deletions
59
.github/helper-bot/github-helper.js
vendored
Normal file
59
.github/helper-bot/github-helper.js
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
if (!process.env.CI) {
|
||||
// mock a bunch of things for testing locally -- https://github.com/actions/toolkit/issues/71
|
||||
process.env.GITHUB_REPOSITORY = 'PrismarineJS/bedrock-protocol'
|
||||
process.env.GITHUB_EVENT_NAME = 'issue_comment'
|
||||
process.env.GITHUB_SHA = 'cb2fd97b6eae9f2c7fee79d5a86eb9c3b4ac80d8'
|
||||
process.env.GITHUB_REF = 'refs/heads/master'
|
||||
process.env.GITHUB_WORKFLOW = 'Issue comments'
|
||||
process.env.GITHUB_ACTION = 'run1'
|
||||
process.env.GITHUB_ACTOR = 'test-user'
|
||||
module.exports = { getIssueStatus: () => ({}), updateIssue: () => {}, createIssue: () => {} }
|
||||
return
|
||||
}
|
||||
|
||||
// const { Octokit } = require('@octokit/rest') // https://github.com/octokit/rest.js
|
||||
const github = require('@actions/github')
|
||||
|
||||
const token = process.env.GITHUB_TOKEN
|
||||
const octokit = github.getOctokit(token)
|
||||
const context = github.context
|
||||
|
||||
async function getIssueStatus (title) {
|
||||
// https://docs.github.com/en/rest/reference/search#search-issues-and-pull-requests
|
||||
const existingIssues = await octokit.rest.search.issuesAndPullRequests({
|
||||
q: `is:issue repo:${process.env.GITHUB_REPOSITORY} in:title ${title}`
|
||||
})
|
||||
// console.log('Existing issues', existingIssues)
|
||||
const existingIssue = existingIssues.data.items.find(issue => issue.title === title)
|
||||
|
||||
if (!existingIssue) return {}
|
||||
|
||||
return { open: existingIssue.state === 'open', closed: existingIssue.state === 'closed', id: existingIssue.number }
|
||||
}
|
||||
|
||||
async function updateIssue (id, payload) {
|
||||
const issue = await octokit.rest.issues.update({
|
||||
...context.repo,
|
||||
issue_number: id,
|
||||
body: payload.body
|
||||
})
|
||||
console.log(`Updated issue ${issue.data.title}#${issue.data.number}: ${issue.data.html_url}`)
|
||||
}
|
||||
|
||||
async function createIssue (payload) {
|
||||
const issue = await octokit.rest.issues.create({
|
||||
...context.repo,
|
||||
...payload
|
||||
})
|
||||
console.log(`Created issue ${issue.data.title}#${issue.data.number}: ${issue.data.html_url}`)
|
||||
}
|
||||
|
||||
async function close (id, reason) {
|
||||
if (reason) await octokit.rest.issues.createComment({ ...context.repo, issue_number: id, body: reason })
|
||||
const issue = await octokit.rest.issues.update({ ...context.repo, issue_number: id, state: 'closed' })
|
||||
console.log(`Closed issue ${issue.data.title}#${issue.data.number}: ${issue.data.html_url}`)
|
||||
}
|
||||
|
||||
if (process.env.CI) {
|
||||
module.exports = { getIssueStatus, updateIssue, createIssue, close }
|
||||
}
|
||||
137
.github/helper-bot/index.js
vendored
Normal file
137
.github/helper-bot/index.js
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// Automatic version update checker for Minecraft bedrock edition.
|
||||
const fs = require('fs')
|
||||
const cp = require('child_process')
|
||||
const helper = require('./github-helper')
|
||||
const latestVesionEndpoint = 'https://itunes.apple.com/lookup?bundleId=com.mojang.minecraftpe'
|
||||
const changelogURL = 'https://feedback.minecraft.net/hc/en-us/sections/360001186971-Release-Changelogs'
|
||||
|
||||
// Relevant infomation for us is:
|
||||
// "version": "1.17.10",
|
||||
// "currentVersionReleaseDate": "2021-07-13T15:35:49Z",
|
||||
// "releaseNotes": "What's new in 1.17.10:\nVarious bug fixes",
|
||||
|
||||
function buildFirstIssue (title, result, externalPatches) {
|
||||
let commitData = ''
|
||||
let protocolVersion = '?'
|
||||
const date = new Date(result.currentVersionReleaseDate).toUTCString()
|
||||
|
||||
for (const name in externalPatches) {
|
||||
commitData += '### ' + name + '\n'
|
||||
const [patches, diff] = externalPatches[name]
|
||||
for (const [name, url] of patches) {
|
||||
commitData += `<a href="${url}">${name}</a>\n`
|
||||
}
|
||||
commitData += `\n**[See the diff between *${result.currentVersionReleaseDate}* and now](${diff})**\n`
|
||||
}
|
||||
try { protocolVersion = getProtocolVersion() } catch (e) { console.log(e) }
|
||||
|
||||
return {
|
||||
title,
|
||||
body: `
|
||||
A new Minecraft Bedrock version is available (as of ${date}), version **${result.version}**
|
||||
|
||||
## Official Changelog
|
||||
* ${result.releaseNotes} *(via App Store)*
|
||||
* ${changelogURL}
|
||||
|
||||
## 3rd party protocol patches
|
||||
${commitData}
|
||||
|
||||
## Protocol Details
|
||||
(I will close this issue automatically if "${result.version}" is added to index.d.ts on "master" and there are no X's below)
|
||||
<table>
|
||||
<tr><td><b>Name</b></td><td>${result.version}</td>
|
||||
<tr><td><b>Protocol ID</b></td><td>${protocolVersion}</td>
|
||||
<!-- TODO ... automatically fetch server, test and grab relevant information and dump
|
||||
<tr><td><b>Partly Already Compatible</b></td><td></td>
|
||||
<tr><td><b>Protocol Dumpers Work</b></td><td></td>
|
||||
-->
|
||||
</table>
|
||||
|
||||
-----
|
||||
|
||||
🤖 I am a bot, I check for updates every 2 hours without a trigger. You can close this PR to prevent any further updates.
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
function getCommitsInRepo (repo, containing, since) {
|
||||
const endpoint = `https://api.github.com/repos/${repo}/commits`
|
||||
console.log('Getting', endpoint)
|
||||
cp.execSync(`curl -L ${endpoint} -o commits.json`, { stdio: 'inherit', shell: true })
|
||||
const commits = JSON.parse(fs.readFileSync('./commits.json', 'utf-8'))
|
||||
const relevant = []
|
||||
for (const commit of commits) {
|
||||
if (commit.commit.message.includes(containing)) {
|
||||
console.log('commit url', commit.html_url)
|
||||
relevant.push([commit.commit.message, commit.html_url])
|
||||
}
|
||||
}
|
||||
if (since) {
|
||||
cp.execSync(`curl -L ${endpoint}?since=${since} -o commits.json`, { stdio: 'inherit', shell: true })
|
||||
const commits = JSON.parse(fs.readFileSync('./commits.json', 'utf-8'))
|
||||
const head = commits[0].sha
|
||||
const tail = commits[commits.length - 1].sha
|
||||
return [relevant, `https://github.com/${repo}/compare/${tail}..${head}`]
|
||||
}
|
||||
return [relevant]
|
||||
}
|
||||
|
||||
function getProtocolVersion () {
|
||||
if (!fs.existsSync('./ProtocolInfo.php')) cp.execSync('curl -LO https://raw.githubusercontent.com/pmmp/PocketMine-MP/stable/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php', { stdio: 'inherit', shell: true })
|
||||
const currentApi = fs.readFileSync('./ProtocolInfo.php', 'utf-8')
|
||||
const [, latestProtocolVersion] = currentApi.match(/public const CURRENT_PROTOCOL = (\d+);/)
|
||||
return latestProtocolVersion
|
||||
}
|
||||
|
||||
async function fetchLatest () {
|
||||
if (!fs.existsSync('./results.json')) cp.execSync(`curl -L ${latestVesionEndpoint} -o results.json`, { stdio: 'inherit', shell: true })
|
||||
const json = require('./results.json')
|
||||
const result = json.results[0]
|
||||
// console.log(json)
|
||||
|
||||
if (!fs.existsSync('./index.d.ts')) cp.execSync('curl -LO https://raw.githubusercontent.com/PrismarineJS/bedrock-protocol/master/index.d.ts', { stdio: 'inherit', shell: true })
|
||||
const currentApi = fs.readFileSync('./index.d.ts', 'utf-8')
|
||||
const supportedVersions = currentApi.match(/type Version = ([^\n]+)/)[1].replace(/\||'/g, ' ').split(' ').map(k => k.trim()).filter(k => k.length)
|
||||
console.log(supportedVersions)
|
||||
|
||||
let { version, currentVersionReleaseDate, releaseNotes } = result
|
||||
console.log(version, currentVersionReleaseDate, releaseNotes)
|
||||
|
||||
const title = `Support Minecraft ${result.version}`
|
||||
|
||||
const issueStatus = await helper.getIssueStatus(title)
|
||||
|
||||
if (supportedVersions.includes(version)) {
|
||||
if (issueStatus.open) {
|
||||
helper.close(issueStatus.id, `Closing as ${version} is now supported`)
|
||||
}
|
||||
console.log('Latest version is supported.')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (issueStatus.closed) {
|
||||
// We already made an issue, but someone else already closed it, don't do anything else
|
||||
console.log('I already made an issue, but it was closed')
|
||||
return
|
||||
}
|
||||
|
||||
version = version.replace('.0', '')
|
||||
const issuePayload = buildFirstIssue(title, result, {
|
||||
PocketMine: getCommitsInRepo('pmmp/PocketMine-MP', version, currentVersionReleaseDate),
|
||||
gophertunnel: getCommitsInRepo('Sandertv/gophertunnel', version, currentVersionReleaseDate),
|
||||
CloudburstMC: getCommitsInRepo('CloudburstMC/Protocol', version, currentVersionReleaseDate)
|
||||
})
|
||||
|
||||
if (issueStatus.open) {
|
||||
helper.updateIssue(issueStatus.id, issuePayload)
|
||||
} else {
|
||||
helper.createIssue(issuePayload)
|
||||
}
|
||||
|
||||
fs.writeFileSync('./issue.md', issuePayload.body)
|
||||
console.log('OK, wrote to ./issue.md', issuePayload)
|
||||
}
|
||||
|
||||
fetchLatest()
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -14,8 +14,6 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
env:
|
||||
FORCE_BUILD: true
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
|
|
|
|||
24
.github/workflows/update-helper.yml
vendored
Normal file
24
.github/workflows/update-helper.yml
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: Update Helper
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 */2 * * *"
|
||||
|
||||
jobs:
|
||||
helper:
|
||||
name: update-checker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@master
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.0.0
|
||||
- name: Install Github Actions toolkit
|
||||
run: npm i @actions/github
|
||||
# The env vars contain the relevant trigger information, so we don't need to pass it
|
||||
- name: Runs helper
|
||||
run: cd .github/helper-bot && node index.js
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue