mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
120 lines
4.5 KiB
YAML
120 lines
4.5 KiB
YAML
name: Add "status:"-label to PRs based on current state
|
|
|
|
on:
|
|
workflow_run:
|
|
workflows:
|
|
- PR-Review submitted
|
|
types: [completed]
|
|
|
|
permissions:
|
|
pull-requests: write
|
|
issues: write
|
|
|
|
jobs:
|
|
review_update:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: 'Download artifact'
|
|
uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
run_id: context.payload.workflow_run.id,
|
|
});
|
|
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
|
return artifact.name == "review-event"
|
|
})[0];
|
|
let download = await github.rest.actions.downloadArtifact({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
artifact_id: matchArtifact.id,
|
|
archive_format: 'zip',
|
|
});
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const temp = '${{ runner.temp }}/artifacts';
|
|
if (!fs.existsSync(temp)){
|
|
fs.mkdirSync(temp);
|
|
}
|
|
fs.writeFileSync(path.join(temp, 'review-event.zip'), Buffer.from(download.data));
|
|
|
|
- name: 'Unzip artifact'
|
|
run: unzip "${{ runner.temp }}/artifacts/review-event.zip" -d "${{ runner.temp }}/artifacts"
|
|
|
|
- name: Update status labels based on review
|
|
uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
const data = JSON.parse(fs.readFileSync('${{ runner.temp }}/artifacts/event.json', 'utf8'));
|
|
|
|
const owner = data.repository.owner;
|
|
const repo = data.repository.name;
|
|
const prNumber = data.pull_request.number;
|
|
const reviewState = data.review.state;
|
|
const reviewBody = data.review.body;
|
|
|
|
const changeLabel = async (currentLabels, newLabel) => {
|
|
// Remove all "status:[...]" labels
|
|
for (const label of currentLabels) {
|
|
await github.rest.issues.removeLabel({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber,
|
|
name: label.name
|
|
}).catch(() => {}) // ignore if already removed
|
|
}
|
|
|
|
// Add new label
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber,
|
|
labels: [newLabel]
|
|
})
|
|
core.info(`Added label: ${newLabel}`)
|
|
}
|
|
|
|
const { data: existingLabels } = await github.rest.issues.listLabelsOnIssue({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber
|
|
})
|
|
const statusLabels = existingLabels.filter(l => l.name.startsWith('status:'))
|
|
const is_approved = statusLabels.some(l => l.name === 'status:approved' || l.name === 'status:ready to merge')
|
|
|
|
// https://github.com/Reviewable/Reviewable/issues/1163
|
|
// other users cannot approve reviewers, requires permissions to actually say `reviewState == 'approved'`
|
|
const approve = reviewState === 'approved' || reviewBody.includes("complete! all files reviewed, all discussions resolved")
|
|
|
|
const R = data.review.reviewer; // reviewer
|
|
const P = data.pull_request.author; // PR author
|
|
const O = owner; // repo owner (by repo name)
|
|
|
|
let new_label = null;
|
|
|
|
if (is_approved && approve) {
|
|
core.info('PR is already approved and review is another approval. No label change needed.')
|
|
return;
|
|
}
|
|
|
|
if (approve && R === O) {
|
|
newLabel = 'status:approved' // standard way of approval: owner appoves PR
|
|
} else if (approve && P === O && R !== O) {
|
|
newLabel = 'status:approved' // if owner is author, someone else must approve
|
|
} else if (P === R) {
|
|
newLabel = 'status:waiting for review'
|
|
} else if (P !== R && !approve) {
|
|
newLabel = 'status:waiting for author'
|
|
} else {
|
|
core.info('No matching condition for new label.')
|
|
core.info(`Review state: ${reviewState}, PR author: ${P}, Reviewer: ${R}, Repo owner: ${O}`)
|
|
}
|
|
|
|
if (newLabel) {
|
|
await changeLabel(statusLabels, newLabel)
|
|
}
|
|
|