Unciv/.github/workflows/uncivbot.yml

163 lines
7.3 KiB
YAML
Raw Normal View History

2021-01-21 03:28:19 +07:00
name: UncivBot
2021-01-24 04:47:11 +07:00
on:
issue_comment:
workflow_dispatch:
2021-01-21 03:28:19 +07:00
jobs:
summary:
if: github.event_name == 'issue_comment' && github.event.comment.body == 'summary' && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
# This is the only place I could find an apparent list of valid author associations. Also, at least they're not case-sensitive: https://docs.github.com/en/graphql/reference/enums#commentauthorassociation https://docs.github.com/en/actions/learn-github-actions/expressions#contains
2021-01-21 03:28:19 +07:00
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
2021-01-21 03:56:45 +07:00
var result = await github.repos.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 50 });
2021-01-21 03:58:45 +07:00
var commitSummary = "";
var ownerToCommits = {}
var reachedPreviousVersion = false
result.data.forEach(commit => {
2021-01-21 04:05:16 +07:00
if (reachedPreviousVersion) return
2021-01-21 04:03:36 +07:00
var author = commit.author.login
2021-01-21 04:05:16 +07:00
if (author=="uncivbot[bot]") return
2021-01-21 04:03:36 +07:00
var commitMessage = commit.commit.message.split("\n")[0];
2021-01-21 04:16:46 +07:00
if (commitMessage.match(/^\d+\.\d+\.\d+$/)){ // match EXACT version, like 3.4.55 ^ is for start-of-line, $ for end-of-line
2021-01-21 04:05:16 +07:00
reachedPreviousVersion=true
console.log(commitMessage)
return
}
2021-01-24 00:28:46 +07:00
if (commitMessage.startsWith("Merge ") || commitMessage.startsWith("Update ")) return
2021-01-21 04:06:54 +07:00
commitMessage = commitMessage.replace(/\(\#\d+\)/,"") // match PR auto-text, like (#2345)
2021-01-21 04:11:21 +07:00
if (author != context.repo.owner){
2021-01-21 04:31:01 +07:00
if (ownerToCommits[author] == undefined) ownerToCommits[author]=[]
2021-01-21 04:12:41 +07:00
ownerToCommits[author].push(commitMessage)
2021-01-21 04:06:54 +07:00
}
else commitSummary += "\n\n" + commitMessage
});
2021-01-21 04:21:38 +07:00
Object.entries(ownerToCommits).forEach(entry => {
2021-01-21 04:27:22 +07:00
const [author, commits] = entry;
2021-01-21 04:31:01 +07:00
if (commits.length==1) commitSummary += "\n\n" + commits[0] + " - By "+author
2021-01-21 04:16:46 +07:00
else {
commitSummary += "\n\nBy "+author+":"
2021-01-21 04:28:48 +07:00
commits.forEach(commitMessage => { commitSummary += "\n- "+commitMessage })
2021-01-21 04:16:46 +07:00
}
})
2021-01-21 03:47:27 +07:00
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
2021-01-21 03:58:45 +07:00
body: commitSummary
2021-01-21 03:47:27 +07:00
})
merge_translations:
if: github.event_name == 'workflow_dispatch' || (github.event.comment.body == 'merge translations' && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association))
# This is the only place I could find an apparent list of valid author associations. Also, at least they're not case-sensitive: https://docs.github.com/en/graphql/reference/enums#commentauthorassociation https://docs.github.com/en/actions/learn-github-actions/expressions#contains
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
2021-01-25 00:22:36 +07:00
# SO, the story is that when using the default access token you CANNOT merge PRs from forks.
# _Badly_ documented in multiple places, including here: https://docs.github.com/en/actions/reference/authentication-in-a-workflow
# To get around this, we created a Personal Access Token,
# put it as one of the secrets in the repo settings (https://github.com/yairm210/Unciv/settings/secrets/actions),
# and use that instead.
2021-01-25 00:09:39 +07:00
github-token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
script: |
2021-01-25 00:31:58 +07:00
const repo = {
owner: context.repo.owner,
repo: context.repo.repo }
async function branchExists(branchName) {
try {
2021-01-25 00:31:58 +07:00
await github.git.getRef({...repo, ref: 'heads/' + branchName })
return true
} catch (err) {
return false
}
}
async function getDefaultBranch() {
2021-01-25 00:39:34 +07:00
var repoData = await github.repos.get(repo)
return repoData.data.default_branch
}
2021-01-24 00:28:46 +07:00
var translations = "translations"
2021-01-24 00:28:46 +07:00
async function createTranslationBranchIfNeeded() {
if (await branchExists(translations)) return
var defaultBranch = await getDefaultBranch()
2021-01-24 01:09:56 +07:00
2021-01-25 00:31:58 +07:00
var currentHead = await github.git.getRef({...repo, ref: 'heads/' + defaultBranch })
2021-01-24 01:09:56 +07:00
2021-01-24 00:28:46 +07:00
var currentSha = currentHead.data.object.sha
2021-01-24 00:35:04 +07:00
console.log("Current sha: " + currentSha)
2021-01-24 01:09:56 +07:00
2021-01-25 00:31:58 +07:00
await github.git.createRef({...repo,
2021-01-24 00:28:46 +07:00
ref: `refs/heads/`+translations,
2021-01-24 00:32:05 +07:00
sha: currentSha })
2021-01-24 01:09:56 +07:00
2021-01-25 00:31:58 +07:00
await github.issues.createComment({...repo,
2021-01-24 00:32:05 +07:00
issue_number: context.issue.number,
body: 'Translations branch created' })
2021-01-24 00:28:46 +07:00
}
2021-01-24 00:52:58 +07:00
async function mergeExistingTranslationsIntoBranch(){
2021-01-25 00:31:58 +07:00
var translationPrs = await github.pulls.list({ ...repo, state: "open" })
2021-01-24 01:09:56 +07:00
2021-01-25 00:22:36 +07:00
// When we used a forEach loop here, only one merge would happen at each run,
// because we essentially started multiple async tasks in parallel and they conflicted.
// Instead, we use X of Y as per https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
for (const pr of translationPrs.data) {
2021-01-24 01:31:25 +07:00
if (pr.labels.some(label => label.name == "mergeable translation"))
2021-01-24 01:48:50 +07:00
await tryMergePr(pr)
2021-01-25 00:22:36 +07:00
}
2021-01-24 00:52:58 +07:00
}
2021-01-24 01:48:50 +07:00
async function tryMergePr(pr){
if (pr.base.ref != translations)
2021-01-25 00:31:58 +07:00
await github.pulls.update({ ...repo,
2021-01-24 01:48:50 +07:00
pull_number: pr.number,
base: translations })
2021-01-24 04:03:18 +07:00
try {
2021-01-25 00:31:58 +07:00
await github.pulls.merge({...repo,
2021-01-24 01:48:50 +07:00
pull_number: pr.number,
merge_method: "squash" })
2021-01-24 04:43:49 +07:00
console.log("Merged #"+pr.number+", "+pr.title)
2021-01-24 04:03:18 +07:00
} catch (err) {
console.log(err)
}
2021-01-24 01:48:50 +07:00
}
2021-01-24 00:28:46 +07:00
2021-01-25 00:36:48 +07:00
async function createTranslationPrIfNeeded() {
2021-01-25 00:31:58 +07:00
var translationPulls = await github.pulls.list({...repo,
state: "open",
head: context.repo.owner + ":" + translations });
if (translationPulls.data.length == 0) {
var defaultBranch = await getDefaultBranch(context);
await github.pulls.create({...repo,
title: "Translations update",
head: translations,
base: defaultBranch });
await github.issues.createComment({...repo,
issue_number: context.issue.number,
body: 'Translations PR created' });
}
}
2021-01-25 00:36:48 +07:00
await createTranslationBranchIfNeeded()
await mergeExistingTranslationsIntoBranch()
await createTranslationPrIfNeeded()