softprops/action-gh-release

repository·master·Indexed 26 days ago

https://github.com/softprops/action-gh-release

A GitHub Action for automating the creation of GitHub Releases and uploading release assets across Linux, Windows, and macOS. It supports glob expressions for file uploads, custom release notes via body_path, automatic release note generation, and integration with GitHub Discussions. Version 3.0.2.

Tokens
3.3K
Snippets
7
Records
17
Agent score
91%

What's inside action-gh-release

  1. Use action-gh-release to create GitHub Releases

    master
    The softprops/action-gh-release GitHub Action allows you to create GitHub Releases across Linux, Windows, and macOS virtual environments. It can be used to automate the creation of releases and the uploading of assets during your CI/CD workflow.
  2. Use external release notes

    master

    You can load release notes from a file in your repository using body_path. This allows you to use custom changelog generators.

    If you are using GitHub's built-in generate_release_notes: true, you can optionally pin the comparison base using previous_tag to control the range of changes included in the notes.

    - name: Release
      uses: softprops/action-gh-release@v3
      if: github.ref_type == 'tag'
      with:
        body_path: ${{ github.workspace }}-CHANGELOG.txt
        repository: my_gh_org/my_gh_repo
        token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
  3. Limit releases to pushes to tags

    master

    To prevent the action from running on every push (like to branches), gate the release step using step.if or configure the workflow on: push trigger to only listen for specific tag patterns.

    Option 1: Using step.if Use if: github.ref_type == 'tag' to ensure the release step only executes when a tag is pushed.

    Option 2: Using push tag filters Configure your workflow trigger to only fire on specific tag patterns (e.g., v*.*.*).

    name: Main
    
    on: push
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v6
          - name: Release
            uses: softprops/action-gh-release@v3
            if: github.ref_type == 'tag'
  4. Upload release assets

    master

    Use the with.files input to upload files to a GitHub release. The input accepts a newline-delimited list of glob expressions or direct filenames.

    • Multiple files: Use the YAML | syntax for multi-line strings.
    • Subdirectories: If assets are in a subdirectory, set working_directory and keep files patterns relative to it.
    • Windows: Both \ and / path separators are supported.
    • Escaping: If a filename contains glob metacharacters like [ or ], you must escape them in the pattern.
    • Existing Releases: If a release for the tag already exists, the action will update it with the new assets.
    - name: Release
      uses: softprops/action-gh-release@v3
      if: github.ref_type == 'tag'
      with:
        working_directory: dist
        files: |
          Release.txt
          checksums/*.txt
  5. Configure required permissions

    master

    The action requires specific permissions on the GitHub integration token:

    Standard release:

    permissions:
      contents: write

    When using discussion_category_name:

    permissions:
      contents: write
      discussions: write

    Note: If you want to trigger other workflows on the release event (e.g., on: release: published), you must use a Personal Access Token (PAT), as the default GITHUB_TOKEN does not trigger subsequent workflow runs.

  6. Specify release assets using `files`

    master

    The files input allows you to specify one or more files or glob patterns to upload as release assets. You can provide them in two ways:

    1. Newline-separated list
    2. Comma-separated list (supports complex patterns containing braces like {a,b})

    Example of a multi-line input:

    files: |
      dist/*.js
      assets/*.zip
  7. Configure Authentication via Token

    master

    The action requires a GitHub token to create releases. It follows this priority for authentication:

    1. token input (INPUT_TOKEN): If provided, this explicitly overrides the default GitHub token.
    2. GITHUB_TOKEN environment variable: Used if no explicit token is provided.

    If neither is provided, the action will fail to authenticate.

  8. Access action outputs

    master

    The following outputs are available via ${{ steps.<step-id>.outputs }}:

    NameTypeDescription
    assetsStringJSON array of updated/overwritten asset info (matches GitHub REST API format minus uploader)
    idStringRelease ID
    upload_urlStringURL for uploading assets to the release
    urlStringGithub.com URL for the release

    Example: Get download URL of the first asset {{ fromJSON(steps.<step-id>.outputs.assets)[0].browser_download_url }}

  9. Configure action inputs

    master

    The following inputs are available via step.with:

    NameTypeDescription
    append_bodyBooleanAppend to existing body instead of overwriting it
    bodyStringText communicating notable changes in this release
    body_pathStringPath to load text communicating notable changes in this release
    discussion_category_nameStringCategory name for a discussion to be created and linked to the release
    draftBooleanKeep the release as a draft. Defaults to false.
    fail_on_unmatched_filesBooleanFail if any of the files globs match nothing
    filesStringNewline-delimited globs of paths to assets to upload
    generate_release_notesBooleanAutomatically generate name and body for this release
    make_latestStringSet as latest release (true, false, or legacy)
    nameStringName of the release (defaults to tag name)
    overwrite_filesBooleanWhether to overwrite existing files (defaults to true)
    prereleaseBooleanIndicator of whether or not is a prerelease
    previous_tagStringComparison base for generate_release_notes
    preserve_orderBooleanUpload assets sequentially in the provided order
    rag_nameStringName of a tag (defaults to github.ref_name)
    repositoryStringTarget repository in <owner>/<repo> format
    tag_nameStringName of a tag (defaults to github.ref_name)
    target_commitishStringCommit/branch to create the tag from
    tokenStringAuthorized GitHub token or PAT (defaults to ${{ github.token }})
    working_directoryStringBase directory to resolve files globs against
  10. Handle unmatched file patterns

    master

    When configuring the files input, you can control how the action behaves if a provided glob pattern or file path does not match any actual files in the working directory.

    • If fail_on_unmatched_files is set to true, the action will throw an error and fail the workflow if a pattern is unmatched.
    • If fail_on_unmatched_files is not set (or false), the action will log a warning for the unmatched pattern but continue execution.
  11. Identify immutable release upload failures

    master

    If you attempt to upload an asset to a release that has already been published, GitHub will return a 422 error. The library identifies this as an immutable release failure.

    Workaround: Upload assets to a draft release first, then publish the release. Draft pre-releases publish with the release.published event, allowing for asset uploads before the final publication.

  12. Use the Releaser interface to manage GitHub releases

    master

    The Releaser interface defines the core methods for interacting with GitHub releases. You can implement this interface to wrap the GitHub REST API for creating, updating, deleting, and managing release assets.

    export interface Releaser {
      getReleaseByTag(params: { owner: string; repo: string; tag: string }): Promise<{ data: Release }>;
    
      createRelease(params: ReleaseMutationParams): Promise<{ data: Release }>;
    
      updateRelease(
        params: ReleaseMutationParams & {
          release_id: number;
          target_commitish: string;
        },
      ): Promise<{ data: Release }>;
    
      finalizeRelease(params: {
        owner: string;
        repo: string;
        release_id: number;
        make_latest: 'true' | 'false' | 'legacy' | undefined;
        discussion_category_name: string | undefined;
      }): Promise<void>;
    
      allReleases(params: { owner: string; repo: string }): AsyncIterable<{ data: Release[] }>;
    
      listReleaseAssets(params: {
        owner: string;
        repo: string;
        release_id: number;
      }): Promise<Array<{ id: number; name: string; label?: string | null; [key: string]: any }>>;
    
      deleteReleaseAsset(params: {
        owner: string;
        repo: string;
        release_id: number;
        asset_id: number;
      }): Promise<void>;
    
      deleteRelease(params: { owner: string; repo: string; release_id: number }): Promise<void>;
    
      updateReleaseAsset(params: {
        asset_id: number;
        name: string;
        label: string;
      }): Promise<{ data: any }>;
    
      uploadReleaseAsset(params: {
        url: string;
        size: number;
        mime: string;
        token: string;
        data: UploadBody;
      }): Promise<{ status: number; data: any }>;
    }