Files
verilator/.github/workflows/pr-automation.yml
T

282 lines
11 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", "RTLMeter", "Regression"]
types: [completed]
push: # A pull request can start conflicting when its base branch moves
branches: [master]
permissions:
contents: read # To check out the local action, everything else uses the CI app token
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.repository == 'verilator/verilator'
&& github.event_name == 'pull_request_target'
runs-on: ubuntu-slim
steps:
# Label as the CI app, and not with 'github.token', as events from the
# latter do not create workflow runs, so the labels would drive nothing
- name: Generate access token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.VERILATOR_CI_ID }}
private-key: ${{ secrets.VERILATOR_CI_KEY }}
permission-pull-requests: write
- name: "Add 'pr: regression' label on open"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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' }}
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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' }}
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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
conflicting:
name: Conflict check
# A pull request can start conflicting when its own head moves, or when the
# base branch moves under it, so sweep the open pull requests on both.
if: |
github.repository == 'verilator/verilator'
&& (github.event_name == 'push'
|| (github.event_name == 'pull_request_target'
&& github.event.action == 'synchronize'))
runs-on: ubuntu-slim
steps:
# Label as the CI app, and not with 'github.token', as events from the
# latter do not create workflow runs, so the labels would drive nothing
- name: Generate access token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.VERILATOR_CI_ID }}
private-key: ${{ secrets.VERILATOR_CI_KEY }}
permission-pull-requests: write
- name: "Update the 'pr-blocked: needs-rebase' label"
uses: eps1lon/actions-label-merge-conflict@0273be72a0bbd58fcd71d0d6c02c209b50d1e5e1 # 3.1.0
with:
dirtyLabel: "pr-blocked: needs-rebase"
repoToken: ${{ steps.generate-token.outputs.token }}
regression-complete:
name: Regression complete
if: |
github.repository == 'verilator/verilator'
&& 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
steps:
# Label as the CI app, and not with 'github.token', as events from the
# latter do not create workflow runs, so the labels would drive nothing
- name: Generate access token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.VERILATOR_CI_ID }}
private-key: ${{ secrets.VERILATOR_CI_KEY }}
permission-actions: read
permission-pull-requests: write
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
sparse-checkout: .github/actions/update-pr-label
- name: Get the pull request number
id: pr
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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
echo "number=$(cat pr-number.txt)" >> "$GITHUB_OUTPUT"
- name: "Update the 'pr-blocked: fix-regression' label"
if: ${{ steps.pr.outputs.number }}
uses: ./.github/actions/update-pr-label
with:
token: ${{ steps.generate-token.outputs.token }}
pr-number: ${{ steps.pr.outputs.number }}
head-sha: ${{ github.event.workflow_run.head_sha }}
label: "pr-blocked: fix-regression"
set: ${{ github.event.workflow_run.conclusion == 'failure' }}
rtlmeter-complete:
name: RTLMeter complete
if: |
github.repository == 'verilator/verilator'
&& github.event_name == 'workflow_run'
&& github.event.workflow_run.name == 'RTLMeter'
&& github.event.workflow_run.event == 'pull_request'
&& (github.event.workflow_run.conclusion == 'success'
|| github.event.workflow_run.conclusion == 'failure')
runs-on: ubuntu-slim
steps:
# Label as the CI app, and not with 'github.token', as events from the
# latter do not create workflow runs, so the labels would drive nothing
- name: Generate access token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.VERILATOR_CI_ID }}
private-key: ${{ secrets.VERILATOR_CI_KEY }}
permission-actions: read
permission-pull-requests: write
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
sparse-checkout: .github/actions/update-pr-label
- name: Get the pull request number
id: pr
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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
echo "number=$(cat pr-number.txt)" >> "$GITHUB_OUTPUT"
- name: "Update the 'pr-blocked: fix-rtlmeter' label"
if: ${{ steps.pr.outputs.number }}
uses: ./.github/actions/update-pr-label
with:
token: ${{ steps.generate-token.outputs.token }}
pr-number: ${{ steps.pr.outputs.number }}
head-sha: ${{ github.event.workflow_run.head_sha }}
label: "pr-blocked: fix-rtlmeter"
set: ${{ github.event.workflow_run.conclusion == 'failure' }}
coverage-complete:
name: Coverage complete
if: |
github.repository == 'verilator/verilator'
&& 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'
|| github.event.workflow_run.conclusion == 'failure')
runs-on: ubuntu-slim
steps:
# Label as the CI app, and not with 'github.token', as events from the
# latter do not create workflow runs, so the labels would drive nothing
- name: Generate access token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.VERILATOR_CI_ID }}
private-key: ${{ secrets.VERILATOR_CI_KEY }}
permission-actions: read
permission-pull-requests: write
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
sparse-checkout: .github/actions/update-pr-label
- name: Get the pull request number
id: pr
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
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
echo "number=$(cat pr-number.txt)" >> "$GITHUB_OUTPUT"
- name: "Update the 'pr-blocked: fix-dev-coverage' label"
if: ${{ steps.pr.outputs.number }}
uses: ./.github/actions/update-pr-label
with:
token: ${{ steps.generate-token.outputs.token }}
pr-number: ${{ steps.pr.outputs.number }}
head-sha: ${{ github.event.workflow_run.head_sha }}
label: "pr-blocked: fix-dev-coverage"
set: ${{ github.event.workflow_run.conclusion == 'failure' }}
- name: Get the line coverage
id: coverage
if: ${{ github.event.workflow_run.conclusion == 'success' }}
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |-
# Whether every line the 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
echo "covered=$(cat coverage-status.txt)" >> "$GITHUB_OUTPUT"
- name: "Update the 'pr-blocked: improve-coverage' label"
if: ${{ steps.pr.outputs.number && steps.coverage.outputs.covered }}
uses: ./.github/actions/update-pr-label
with:
token: ${{ steps.generate-token.outputs.token }}
pr-number: ${{ steps.pr.outputs.number }}
head-sha: ${{ github.event.workflow_run.head_sha }}
label: "pr-blocked: improve-coverage"
set: ${{ steps.coverage.outputs.covered != 'true' }}