A GitHub Action that validates PR-issue relationships and optionally enforces assignment requirements.
- Optional Issue Linking: Ensures every PR is linked to an issue via GitHub API
- Optional PR Description Check: Fallback validation that checks PR description for closing issue references (e.g., "Closes #123")
- Optional Assignee Validation: Configurable check that issue assignee matches PR author
- Bot Support: Automatically skips validation for bot-authored PRs
- User Whitelist: Configurable list of users whose PRs can bypass all checks
- Flexible Enforcement: Option to close non-compliant PRs or just post warnings
- Custom Messages: Configurable error messages for different failure types
name: Check PR Issue
on:
pull_request:
types:
- opened
- synchronize
jobs:
check-pr-issue:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: arkid15r/check-pr-issue-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}- uses: arkid15r/check-pr-issue-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
skip_users: 'admin,maintainer'
check_issue_reference: 'true'
require_assignee: 'true'
close_pr_on_failure: 'false'
no_issue_message: 'Please link this PR to an issue before merging.'
assignee_mismatch_message: 'The linked issue must be assigned to you before merging.'| Input | Description | Required | Default |
|---|---|---|---|
github_token |
GitHub token for API access | Yes | - |
skip_users |
Comma-separated list of usernames to skip validation | No | '' |
check_issue_reference |
Whether to allow PRs without a linked issue when the PR description contains a valid closing issue reference | No | false |
require_assignee |
Whether to require issue assignee to match PR author | No | false |
close_pr_on_failure |
Whether to close PR when validation fails | No | true |
no_issue_message |
Error message when PR has no linked issue | No | 'This PR must be linked to an issue before it can be merged.' |
assignee_mismatch_message |
Error message when assignee doesn't match PR author | No | 'The linked issue must be assigned to the PR author before this PR can be merged.' |
When check_issue_reference is enabled, the action will check the PR description for valid closing issue references if no linked issue is found via the GitHub API. This is useful when PRs reference issues in their description but aren't formally linked.
Supported Keywords (case-insensitive):
close,closes,closedfix,fixes,fixedresolve,resolves,resolved
Valid Formats:
Closes #123- References an issue in the same repositoryResolves #10, resolves #123- Multiple issues in one descriptionCloses: #10- Optional colon after keywordCLOSES #10- Case-insensitive matching
Example PR Description:
This PR implements the new feature requested in the issue.
Closes #123
This action requires the following GitHub permissions:
pull-requests: write- To close PRs and post commentsissues: read- To access linked issue information and assigneescontents: read- To read repository contents (standard permission)
These permissions are automatically included in the action definition, but you may need to ensure your workflow has sufficient permissions if using a custom token.
# Install pipx and Poetry (if not already installed)
python -m pip install --user pipx
python -m pipx ensurepath
pipx install poetry
# Install development dependencies (includes package in editable mode)
make install-dev
# Install pre-commit hooks
make pre-commit# Install all dependencies (production + development)
poetry install --with dev
# Install only production dependencies
poetry install --only main
# Run tests
poetry run pytest
# Run linting
poetry run ruff check .
# Format code
poetry run ruff format .
# Run all checks
make checkThis repository includes a test workflow (.github/workflows/test-action.yml) that demonstrates how to use the action in a real environment:
- PR Testing: The workflow runs automatically when a PR is opened
- Basic Configuration: Tests the action with a simple configuration
- Non-blocking: Uses
close_pr_on_failure: 'false'to avoid closing test PRs
# Run tests
make test
# Run tests with coverage
make test-cov# Run linting
make lint
# Format code
make format
# Run all checks
make checkcheck-pr-issue-action/
├── src/check_pr_issue_action/ # Main package code
│ ├── __init__.py # Package initialization
│ ├── main.py # Main entry point
│ ├── config.py # Configuration management
│ ├── validator.py # Validation logic
│ └── pr_manager.py # PR management
├── tests/ # Test suite
├── .github/workflows/ # CI/CD workflows
│ ├── ci.yml # Main CI workflow
│ └── test-action.yml # Action testing workflow
├── action.yml # GitHub Action metadata
├── Dockerfile # Container definition (Alpine Linux)
├── pyproject.toml # Project configuration
└── README.md # Documentation
make install- Install production dependenciesmake install-dev- Install development dependenciesmake test- Run testsmake test-cov- Run tests with coveragemake lint- Run lintingmake format- Format codemake check- Run linting and testsmake clean- Clean up generated filesmake pre-commit- Run pre-commit on all files
The action is built on Alpine Linux for a smaller, more secure container image:
- Base Image:
python:3.11-alpine - Size: ~410MB (significantly smaller than Debian-based images)
- Security: Minimal attack surface with Alpine's security-focused design
- Multi-arch: Supports both AMD64 and ARM64 architectures
- Bot Detection: Automatically skips validation for any PR authored by a bot user
- Skip Users: Bypasses validation for users in the
skip_userslist - Issue Linking: Uses GitHub API to check if PR is linked to an issue
- PR Description Fallback: If
check_issue_referenceis enabled and no linked issue is found, checks the PR description for valid closing keywords (e.g., "Closes #123", "Fixes owner/repo#456"). Supports keywords:close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved - Assignee Validation: If enabled, verifies that the issue assignee matches the PR author
- Enforcement: Either closes the PR or posts a warning message based on configuration
This project is licensed under the MIT License.