mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
164 lines
6.8 KiB
YAML
164 lines
6.8 KiB
YAML
---
|
|
# DESCRIPTION: Github actions config
|
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
|
|
# Drives the automation of a pull request.
|
|
|
|
name: Maintenance - PR automation
|
|
|
|
on:
|
|
pull_request_target: # 'pull_request' can have no write permissions
|
|
types: [opened, synchronize, reopened, closed]
|
|
workflow_run: # To react to the result of a workflow on a pull request
|
|
workflows: ["Code coverage", "Regression"]
|
|
types: [completed]
|
|
|
|
permissions:
|
|
actions: read # To download the artifacts of the triggering run
|
|
pull-requests: write
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
# One job per event source, to avoid startup churn. Use separate gated steps for actions
|
|
jobs:
|
|
pr-event:
|
|
name: PR event
|
|
if: ${{ github.event_name == 'pull_request_target' }}
|
|
runs-on: ubuntu-slim
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: "Add 'pr: regression' label on open"
|
|
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' }}
|
|
run: |-
|
|
gh pr edit "${{ github.event.number }}" \
|
|
--repo "${{ github.repository }}" \
|
|
--add-label 'pr: regression'
|
|
|
|
- name: "Optionally add 'pr: dev-coverage' label on open"
|
|
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' }}
|
|
run: |-
|
|
# Grab changed files
|
|
FILES=$(gh api --paginate \
|
|
"repos/${{ github.repository }}/pulls/${{ github.event.number }}/files" \
|
|
--jq '.[].filename')
|
|
echo "Files changed:"
|
|
echo "${FILES}"
|
|
# Add label if src or include chagned
|
|
if grep -q -E '^(src|include)/' <<< "${FILES}"; then
|
|
gh pr edit "${{ github.event.number }}" \
|
|
--repo "${{ github.repository }}" \
|
|
--add-label 'pr: dev-coverage'
|
|
fi
|
|
|
|
- name: "Remove all 'pr*' labels on close"
|
|
if: ${{ github.event.action == 'closed' }}
|
|
run: |-
|
|
# Filter in 'jq', so an empty result is not an error, as it is with 'grep'
|
|
LABELS=$(gh api \
|
|
"repos/${{ github.repository }}/issues/${{ github.event.number }}/labels?per_page=100" \
|
|
--jq '[.[].name | select(startswith("pr"))] | join(",")')
|
|
if [ -n "${LABELS}" ]; then
|
|
echo "Removing labels: ${LABELS}"
|
|
gh pr edit "${{ github.event.number }}" \
|
|
--repo "${{ github.repository }}" \
|
|
--remove-label "${LABELS}"
|
|
fi
|
|
|
|
regression-complete:
|
|
name: Regression complete
|
|
if: |
|
|
github.event_name == 'workflow_run'
|
|
&& github.event.workflow_run.name == 'Regression'
|
|
&& github.event.workflow_run.event == 'pull_request'
|
|
&& (github.event.workflow_run.conclusion == 'success'
|
|
|| github.event.workflow_run.conclusion == 'failure')
|
|
runs-on: ubuntu-slim
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: "Set the 'pr-blocked: fix-regression' label from the result"
|
|
env:
|
|
SHA: ${{ github.event.workflow_run.head_sha }}
|
|
LABEL: "pr-blocked: fix-regression"
|
|
FAILED: ${{ github.event.workflow_run.conclusion == 'failure' }}
|
|
run: |-
|
|
# The run tells us which pull request it was for
|
|
if ! gh run download "${{ github.event.workflow_run.id }}" --name pr-number; then
|
|
echo "Run has no 'pr-number' artifact"
|
|
exit 0
|
|
fi
|
|
PR=$(cat pr-number.txt)
|
|
# Its state and head as they are now, and whether it carries the
|
|
# label already
|
|
read -r STATE HEAD LABELLED < <(gh pr view "${PR}" \
|
|
--repo "${{ github.repository }}" \
|
|
--json state,headRefOid,labels \
|
|
--jq '"\(.state) \(.headRefOid) \(any(.labels[]; .name == env.LABEL))"')
|
|
# Only act on a change, so a run does not reapply what is already set
|
|
if [ "${STATE}" != OPEN ]; then
|
|
# Closing removes all 'pr*' labels, do not put one back on
|
|
echo "PR #${PR} is ${STATE}"
|
|
elif [ "${HEAD}" != "${SHA}" ]; then
|
|
# Pushed to since, so this result is stale and a new run will decide
|
|
echo "PR #${PR} has moved on from ${SHA}"
|
|
elif [ "${FAILED}" = true ] && [ "${LABELLED}" = false ]; then
|
|
echo "Regression failed, blocking PR #${PR}"
|
|
gh pr edit "${PR}" --repo "${{ github.repository }}" --add-label "${LABEL}"
|
|
elif [ "${FAILED}" = false ] && [ "${LABELLED}" = true ]; then
|
|
echo "Regression succeeded, unblocking PR #${PR}"
|
|
gh pr edit "${PR}" --repo "${{ github.repository }}" --remove-label "${LABEL}"
|
|
else
|
|
echo "No change to PR #${PR}"
|
|
fi
|
|
|
|
coverage-complete:
|
|
name: Coverage complete
|
|
if: |
|
|
github.event_name == 'workflow_run'
|
|
&& github.event.workflow_run.name == 'Code coverage'
|
|
&& github.event.workflow_run.event == 'pull_request'
|
|
&& github.event.workflow_run.conclusion == 'success'
|
|
runs-on: ubuntu-slim
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: "Set the 'pr-blocked: improve-coverage' label from the result"
|
|
env:
|
|
SHA: ${{ github.event.workflow_run.head_sha }}
|
|
LABEL: "pr-blocked: improve-coverage"
|
|
run: |-
|
|
# The run tells us which pull request it was for, and whether every
|
|
# line its patch touches is covered
|
|
if ! gh run download "${{ github.event.workflow_run.id }}" --name coverage-status; then
|
|
echo "Run has no 'coverage-status' artifact"
|
|
exit 0
|
|
fi
|
|
STATUS=$(cat coverage-status.txt)
|
|
PR=${STATUS%% *}
|
|
COVERED=${STATUS##* }
|
|
# Its state and head as they are now, and whether it carries the
|
|
# label already
|
|
read -r STATE HEAD LABELLED < <(gh pr view "${PR}" \
|
|
--repo "${{ github.repository }}" \
|
|
--json state,headRefOid,labels \
|
|
--jq '"\(.state) \(.headRefOid) \(any(.labels[]; .name == env.LABEL))"')
|
|
# Only act on a change, so a run does not reapply what is already set
|
|
if [ "${STATE}" != OPEN ]; then
|
|
# Closing removes all 'pr*' labels, do not put one back on
|
|
echo "PR #${PR} is ${STATE}"
|
|
elif [ "${HEAD}" != "${SHA}" ]; then
|
|
# Pushed to since, so this result is stale and a new run will decide
|
|
echo "PR #${PR} has moved on from ${SHA}"
|
|
elif [ "${COVERED}" = false ] && [ "${LABELLED}" = false ]; then
|
|
echo "Line coverage incomplete, blocking PR #${PR}"
|
|
gh pr edit "${PR}" --repo "${{ github.repository }}" --add-label "${LABEL}"
|
|
elif [ "${COVERED}" = true ] && [ "${LABELLED}" = true ]; then
|
|
echo "Line coverage complete, unblocking PR #${PR}"
|
|
gh pr edit "${PR}" --repo "${{ github.repository }}" --remove-label "${LABEL}"
|
|
else
|
|
echo "No change to PR #${PR}"
|
|
fi
|