workflow/labels: fix scheduled runs (#417250)
This commit is contained in:
commit
e1a3aac6ce
163
.github/workflows/labels.yml
vendored
163
.github/workflows/labels.yml
vendored
@ -69,13 +69,14 @@ jobs:
|
|||||||
// Normally a scheduled run, but could be workflow_dispatch, see above. Go back as far
|
// Normally a scheduled run, but could be workflow_dispatch, see above. Go back as far
|
||||||
// as the last successful run of this workflow to make sure we are not leaving anyone
|
// as the last successful run of this workflow to make sure we are not leaving anyone
|
||||||
// behind on GHA failures.
|
// behind on GHA failures.
|
||||||
|
// Defaults to go back 1 hour on the first run.
|
||||||
return (await github.rest.actions.listWorkflowRuns({
|
return (await github.rest.actions.listWorkflowRuns({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
workflow_id: 'labels.yml',
|
workflow_id: 'labels.yml',
|
||||||
event: 'schedule',
|
event: 'schedule',
|
||||||
status: 'success',
|
status: 'success',
|
||||||
exclude_pull_requests: true
|
exclude_pull_requests: true
|
||||||
})).data.workflow_runs[0]?.created_at
|
})).data.workflow_runs[0]?.created_at ?? new Date().getTime() - 1 * 60 * 60 * 1000
|
||||||
})())
|
})())
|
||||||
core.info('cutoff timestamp: ' + cutoff.toISOString())
|
core.info('cutoff timestamp: ' + cutoff.toISOString())
|
||||||
|
|
||||||
@ -98,96 +99,102 @@ jobs:
|
|||||||
direction: 'desc',
|
direction: 'desc',
|
||||||
...prEventCondition
|
...prEventCondition
|
||||||
},
|
},
|
||||||
async (response, done) => await Promise.all(response.data.map(async (pull_request) => {
|
async (response, done) => (await Promise.allSettled(response.data.map(async (pull_request) => {
|
||||||
const log = (k,v) => core.info(`PR #${pull_request.number} - ${k}: ${v}`)
|
try {
|
||||||
|
const log = (k,v) => core.info(`PR #${pull_request.number} - ${k}: ${v}`)
|
||||||
|
|
||||||
log('Last updated at', pull_request.updated_at)
|
log('Last updated at', pull_request.updated_at)
|
||||||
if (new Date(pull_request.updated_at) < cutoff) return done()
|
if (new Date(pull_request.updated_at) < cutoff) return done()
|
||||||
|
|
||||||
const run_id = (await github.rest.actions.listWorkflowRuns({
|
const run_id = (await github.rest.actions.listWorkflowRuns({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
workflow_id: 'eval.yml',
|
workflow_id: 'eval.yml',
|
||||||
event: 'pull_request_target',
|
event: 'pull_request_target',
|
||||||
// For PR events, the workflow run is still in progress with this job itself.
|
// For PR events, the workflow run is still in progress with this job itself.
|
||||||
status: prEventCondition ? 'in_progress' : 'success',
|
status: prEventCondition ? 'in_progress' : 'success',
|
||||||
exclude_pull_requests: true,
|
exclude_pull_requests: true,
|
||||||
head_sha: pull_request.head.sha
|
head_sha: pull_request.head.sha
|
||||||
})).data.workflow_runs[0]?.id
|
})).data.workflow_runs[0]?.id
|
||||||
|
|
||||||
// Newer PRs might not have run Eval to completion, yet. We can skip them, because this
|
// Newer PRs might not have run Eval to completion, yet. We can skip them, because this
|
||||||
// job will be run as part of that Eval run anyway.
|
// job will be run as part of that Eval run anyway.
|
||||||
log('Last eval run', run_id)
|
log('Last eval run', run_id)
|
||||||
if (!run_id) return;
|
if (!run_id) return;
|
||||||
|
|
||||||
const artifact = (await github.rest.actions.listWorkflowRunArtifacts({
|
const artifact = (await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
run_id,
|
run_id,
|
||||||
name: 'comparison'
|
name: 'comparison'
|
||||||
})).data.artifacts[0]
|
})).data.artifacts[0]
|
||||||
|
|
||||||
// Instead of checking the boolean artifact.expired, we will give us a minute to
|
// Instead of checking the boolean artifact.expired, we will give us a minute to
|
||||||
// actually download the artifact in the next step and avoid that race condition.
|
// actually download the artifact in the next step and avoid that race condition.
|
||||||
log('Artifact expires at', artifact.expires_at)
|
log('Artifact expires at', artifact.expires_at)
|
||||||
if (new Date(artifact.expires_at) < new Date(new Date().getTime() + 60 * 1000)) return;
|
if (new Date(artifact.expires_at) < new Date(new Date().getTime() + 60 * 1000)) return;
|
||||||
|
|
||||||
await artifactClient.downloadArtifact(artifact.id, {
|
await artifactClient.downloadArtifact(artifact.id, {
|
||||||
findBy: {
|
findBy: {
|
||||||
repositoryName: context.repo.repo,
|
repositoryName: context.repo.repo,
|
||||||
repositoryOwner: context.repo.owner,
|
repositoryOwner: context.repo.owner,
|
||||||
token: core.getInput('github-token')
|
token: core.getInput('github-token')
|
||||||
},
|
},
|
||||||
path: path.resolve('comparison'),
|
path: path.resolve(pull_request.number.toString()),
|
||||||
expectedHash: artifact.digest
|
expectedHash: artifact.digest
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get all currently set labels that we manage
|
// Get all currently set labels that we manage
|
||||||
const before =
|
const before =
|
||||||
pull_request.labels.map(({ name }) => name)
|
pull_request.labels.map(({ name }) => name)
|
||||||
.filter(name =>
|
.filter(name =>
|
||||||
name.startsWith('10.rebuild') ||
|
name.startsWith('10.rebuild') ||
|
||||||
name == '11.by: package-maintainer' ||
|
name == '11.by: package-maintainer' ||
|
||||||
name.startsWith('12.approvals:') ||
|
name.startsWith('12.approvals:') ||
|
||||||
name == '12.approved-by: package-maintainer'
|
name == '12.approved-by: package-maintainer'
|
||||||
|
)
|
||||||
|
|
||||||
|
const approvals = new Set(
|
||||||
|
(await github.paginate(github.rest.pulls.listReviews, {
|
||||||
|
...context.repo,
|
||||||
|
pull_number: pull_request.number
|
||||||
|
}))
|
||||||
|
.filter(review => review.state == 'APPROVED')
|
||||||
|
.map(review => review.user.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
const approvals = new Set(
|
const maintainers = new Set(Object.keys(
|
||||||
(await github.paginate(github.rest.pulls.listReviews, {
|
JSON.parse(await readFile(`${pull_request.number}/maintainers.json`, 'utf-8'))
|
||||||
...context.repo,
|
))
|
||||||
pull_number: pull_request.number
|
|
||||||
}))
|
|
||||||
.filter(review => review.state == 'APPROVED')
|
|
||||||
.map(review => review.user.id)
|
|
||||||
)
|
|
||||||
|
|
||||||
const maintainers = new Set(Object.keys(
|
// And the labels that should be there
|
||||||
JSON.parse(await readFile('comparison/maintainers.json', 'utf-8'))
|
const after = JSON.parse(await readFile(`${pull_request.number}/changed-paths.json`, 'utf-8')).labels
|
||||||
))
|
if (approvals.size > 0) after.push(`12.approvals: ${approvals.size > 2 ? '3+' : approvals.size}`)
|
||||||
|
if (Array.from(maintainers).some(m => approvals.has(m))) after.push('12.approved-by: package-maintainer')
|
||||||
|
|
||||||
// And the labels that should be there
|
// Remove the ones not needed anymore
|
||||||
const after = JSON.parse(await readFile('comparison/changed-paths.json', 'utf-8')).labels
|
await Promise.all(
|
||||||
if (approvals.size > 0) after.push(`12.approvals: ${approvals.size > 2 ? '3+' : approvals.size}`)
|
before.filter(name => !after.includes(name))
|
||||||
if (Array.from(maintainers).some(m => approvals.has(m))) after.push('12.approved-by: package-maintainer')
|
.map(name => github.rest.issues.removeLabel({
|
||||||
|
...context.repo,
|
||||||
|
issue_number: pull_request.number,
|
||||||
|
name
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
// Remove the ones not needed anymore
|
// And add the ones that aren't set already
|
||||||
await Promise.all(
|
const added = after.filter(name => !before.includes(name))
|
||||||
before.filter(name => !after.includes(name))
|
if (added.length > 0) {
|
||||||
.map(name => github.rest.issues.removeLabel({
|
await github.rest.issues.addLabels({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
issue_number: pull_request.number,
|
issue_number: pull_request.number,
|
||||||
name
|
labels: added
|
||||||
}))
|
})
|
||||||
)
|
}
|
||||||
|
} catch (cause) {
|
||||||
// And add the ones that aren't set already
|
throw new Error(`Labeling PR #${pull_request.number} failed.`, { cause })
|
||||||
const added = after.filter(name => !before.includes(name))
|
|
||||||
if (added.length > 0) {
|
|
||||||
await github.rest.issues.addLabels({
|
|
||||||
...context.repo,
|
|
||||||
issue_number: pull_request.number,
|
|
||||||
labels: added
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}))
|
})))
|
||||||
|
.filter(({ status }) => status == 'rejected')
|
||||||
|
.map(({ reason }) => core.setFailed(`${reason.message}\n${reason.cause.stack}`))
|
||||||
)
|
)
|
||||||
|
|
||||||
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user