ghaction-rm-releases

About

A GitHub action to remove older releases with their tags based on a regex pattern. This action provides flexible filtering options to keep releases based on recency, age, or exclusion patterns.

Key Features:


Usage

To use the action, add following to your workflow file

- name: Delete Older Releases
  uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "Build*"
    RELEASES_TO_KEEP: 5 # Optional: Keep the 5 most recent releases matching the pattern

Inputs

Following inputs can be used as step.with keys

Name Type Required Default Description
GITHUB_TOKEN String ✅ Yes   GitHub Token with contents:write permissions to delete releases and tags
RELEASE_PATTERN String ✅ Yes   Regular expression pattern to match release tag names for deletion (e.g., "^v1\\..*" for all v1.x releases)
RELEASES_TO_KEEP Number ❌ No 0 Number of most recent matching releases to keep (sorted by creation date). 0 means don’t keep any by count
EXCLUDE_PATTERN String ❌ No "" Regular expression pattern to exclude releases from deletion (e.g., ".*-stable$" to exclude stable releases)
DAYS_TO_KEEP Number ❌ No 0 Number of days to keep releases. Releases newer than this will be preserved. 0 means don’t keep any by age
DRY_RUN Boolean ❌ No false If true, the action will list the releases to be deleted without actually deleting them. Useful for testing.
DELETE_DRAFT_RELEASES_ONLY Boolean ❌ No false If true, only draft releases will be considered for deletion. This filter is applied before RELEASE_PATTERN.
DELETE_PRERELEASES_ONLY Boolean ❌ No false If true, only prereleases will be considered for deletion. This filter is applied before RELEASE_PATTERN.
TARGET_BRANCH_PATTERN String ❌ No "" Regex pattern to match the target branch of a release’s commit. Only releases whose associated commit is on a matching branch will be considered for deletion.

Input Validation

Input Interactions

How the Action Works

The action follows this logic sequence:

  1. Draft Release Filtering: If DELETE_DRAFT_RELEASES_ONLY is true, filter to include only draft releases.
  2. Prerelease Filtering: If DELETE_PRERELEASES_ONLY is true, filter to include only prereleases.
  3. Target Branch Filtering: If TARGET_BRANCH_PATTERN is provided, filter releases to include only those whose associated commit is on a branch matching the pattern.
  4. Pattern Matching: Fetch all releases and filter by RELEASE_PATTERN
  5. Exclusion Filtering: Remove releases matching EXCLUDE_PATTERN (if provided)
  6. Sort by Date: Sort remaining releases by creation date (newest first)
  7. Preservation Logic: For each release, keep it if either condition is true:
    • Count-based: Release is within the RELEASES_TO_KEEP most recent releases
    • Age-based: Release is newer than DAYS_TO_KEEP days old
  8. Deletion: Delete releases and their associated tags that don’t meet either preservation criteria

Key Points

Examples

Basic Usage - Delete All Matching Releases

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "^beta-.*" # Delete all beta releases

Delete Only Draft Releases

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: ".*" # Match all releases (drafts will be filtered by DELETE_DRAFT_RELEASES_ONLY)
    DELETE_DRAFT_RELEASES_ONLY: true # Only target draft releases for deletion

Dry Run - See What Would Be Deleted

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: ".*" # Match all releases
    DRY_RUN: true # List releases to be deleted without actually deleting them

Keep Recent Releases by Count

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "^v[0-9]+\\.[0-9]+\\.[0-9]+$" # Match semantic versions
    RELEASES_TO_KEEP: 3 # Keep the 3 most recent versions

Keep Recent Releases by Age

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: ".*" # Match all releases
    DAYS_TO_KEEP: 30 # Keep releases from the last 30 days

Combined Count and Age Preservation

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "^v.*"
    RELEASES_TO_KEEP: 2 # Keep 2 most recent releases
    DAYS_TO_KEEP: 90 # AND/OR keep releases from last 90 days
    # A release is kept if it's either in the top 2 recent OR newer than 90 days

Exclude Specific Releases

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "^v.*"
    EXCLUDE_PATTERN: ".*-stable$" # Never delete releases ending with '-stable'
    RELEASES_TO_KEEP: 5
- name: Delete Older Releases
  uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "Build*"
    RELEASES_TO_KEEP: 5 # Optional: Keep the 5 most recent releases matching the pattern

Delete Only Prereleases

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: ".*" # Match all releases (prereleases will be filtered by DELETE_PRERELEASES_ONLY)
    DELETE_PRERELEASES_ONLY: true # Only target prereleases for deletion

Delete Releases by Target Branch

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: ".*" # Match all releases
    TARGET_BRANCH_PATTERN: "^release/.*" # Only delete releases whose commit is on a branch starting with 'release/'

Complex Cleanup Strategy

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    RELEASE_PATTERN: "^(dev|test|staging)-.*" # Target dev/test/staging releases
    EXCLUDE_PATTERN: ".*(important|milestone).*" # Protect important releases
    RELEASES_TO_KEEP: 10 # Keep 10 most recent matching releases
    DAYS_TO_KEEP: 7 # Also keep any from the last week

Permissions

Required GitHub Token Permissions

The GitHub token must have the following permissions:

Token Setup Options

- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    # ... other inputs

Option 2: Use Personal Access Token

If you need to run this action on a different repository or need additional permissions:

  1. Create a Personal Access Token with repo scope
  2. Add it as a repository secret (e.g., GH_TOKEN)
  3. Use it in your workflow:
- uses: nikhilbadyal/[email protected]
  with:
    GITHUB_TOKEN: $
    # ... other inputs

Error Handling

The action provides detailed error messages for common issues:

Common Errors and Solutions

Error Message Cause Solution
Need Github Token Missing or empty GITHUB_TOKEN Ensure GITHUB_TOKEN is provided and not empty
RELEASES_TO_KEEP must be a non-negative integer Invalid RELEASES_TO_KEEP value Use a non-negative integer (0, 1, 2, etc.)
DAYS_TO_KEEP must be a non-negative integer Invalid DAYS_TO_KEEP value Use a non-negative integer (0, 1, 2, etc.)
Unable to list release API error or permissions issue Check token permissions and repository access
Unable to delete release Insufficient permissions or release doesn’t exist Verify contents:write permission
Unable to delete tag Insufficient permissions or tag doesn’t exist Verify contents:write permission
Invalid regular expression Malformed regex in patterns Test regex patterns before using

Dry Run / Testing

To test your configuration without actually deleting releases:

  1. Fork your repository
  2. Run the action on the fork first
  3. Verify the behavior matches your expectations
  4. Then apply to your main repository

Troubleshooting

No Releases Found

Unexpected Deletions

Permission Errors

Regex Pattern Help

Performance Considerations

Contributing

Want to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues.

Thanks again for your support, it is much appreciated!